浏览代码

qcacmn: add stats infrastructure to trylock

Remove false positives for locks acquired with trylock.
Trylock was not recording the timestamp when the lock was
acquired. Therefore an old timestamp was used when releasing
the lock and the infrastructure would report that the lock
was held for longer than it was.

With the infrastructure set to generate a crash when a lock
is held too long, these false positives make the system unstable.

Change-Id: I87989b21daf4a2dfb74c8cfbba09be2af53dd1b2
CRs-Fixed: 1111956
Houston Hoffman 8 年之前
父节点
当前提交
805668a63d
共有 1 个文件被更改,包括 27 次插入5 次删除
  1. 27 5
      qdf/inc/qdf_lock.h

+ 27 - 5
qdf/inc/qdf_lock.h

@@ -50,6 +50,8 @@
 struct lock_stats {};
 #define BEFORE_LOCK(x...) do {} while (0)
 #define AFTER_LOCK(x...) do {} while (0)
+#define BEFORE_TRYLOCK(x...) do {} while (0)
+#define AFTER_TRYLOCK(x...) do {} while (0)
 #define BEFORE_UNLOCK(x...) do {} while (0)
 #define qdf_lock_stats_create(x...) do {} while (0)
 #define qdf_lock_stats_destroy(x...) do {} while (0)
@@ -71,7 +73,7 @@ struct lock_stats {
 #define LARGE_CONTENTION QDF_LOG_TIMESTAMP_CYCLES_PER_10_US
 
 #define BEFORE_LOCK(lock, was_locked) \
-{ \
+do { \
 	uint64_t BEFORE_LOCK_time; \
 	uint64_t AFTER_LOCK_time;  \
 	bool BEFORE_LOCK_is_locked = was_locked; \
@@ -99,7 +101,24 @@ struct lock_stats {
 	    lock->stats.max_contention_wait) \
 		lock->stats.max_contention_wait = \
 			AFTER_LOCK_time - BEFORE_LOCK_time; \
-}
+} while (0)
+
+#define BEFORE_TRYLOCK(lock) \
+do { \
+	uint64_t BEFORE_LOCK_time; \
+	uint64_t AFTER_LOCK_time;  \
+	BEFORE_LOCK_time = qdf_get_log_timestamp(); \
+	do {} while (0)
+
+#define AFTER_TRYLOCK(lock, trylock_return) \
+	AFTER_LOCK_time = qdf_get_log_timestamp(); \
+	if (trylock_return) { \
+		lock->stats.acquired++; \
+		lock->stats.last_acquired = AFTER_LOCK_time; \
+		lock->stats.non_contention_time += \
+			(AFTER_LOCK_time - BEFORE_LOCK_time); \
+	} \
+} while (0)
 
 /* max_hold_time in US */
 #define BEFORE_UNLOCK(lock, max_hold_time) \
@@ -121,8 +140,6 @@ do {\
 	} \
 } while (0)
 
-
-
 static inline void qdf_lock_stats_destroy(struct lock_stats *stats)
 {
 	if (QDF_LOCK_STATS_DESTROY_PRINT) {
@@ -239,7 +256,12 @@ static inline int qdf_spin_is_locked(qdf_spinlock_t *lock)
  */
 static inline int qdf_spin_trylock_bh(qdf_spinlock_t *lock)
 {
-	return __qdf_spin_trylock_bh(&lock->lock);
+	int trylock_return;
+	BEFORE_TRYLOCK(lock);
+	trylock_return = __qdf_spin_trylock_bh(&lock->lock);
+	AFTER_TRYLOCK(lock, trylock_return);
+
+	return trylock_return;
 }
 
 int qdf_spin_trylock_bh_outline(qdf_spinlock_t *lock);