lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Wed, 23 Sep 2009 12:46:39 +1000
From:	coder <yangxilkm@...il.com>
To:	Ingo Molnar <mingo@...e.hu>
Cc:	Daniel Walker <dwalker@...o99.com>, linux-kernel@...r.kernel.org
Subject: Re: [PATCH]lock_stat: Adding "nr_contender" and "max_contender" to
	show the degree of contention on ticket spinlock

Thanks Danlel. Here is the patch generated by git format-patch.


 Signed-off-by: Yang Xi <yangxilkm@...il.com>

---
 arch/x86/include/asm/spinlock.h |    9 +++++++++
 include/linux/lockdep.h         |    2 ++
 include/linux/spinlock.h        |    4 ++++
 kernel/lockdep.c                |   21 ++++++++++++++++++++-
 kernel/lockdep_proc.c           |    8 ++++++--
 5 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h
index 4e77853..a2396d8 100644
--- a/arch/x86/include/asm/spinlock.h
+++ b/arch/x86/include/asm/spinlock.h
@@ -172,6 +172,15 @@ static inline int __ticket_spin_is_contended(raw_spinlock_t *lock)
 	return (((tmp >> TICKET_SHIFT) - tmp) & ((1 << TICKET_SHIFT) - 1)) > 1;
 }
 
+static inline int __ticket_spin_nr_contender(raw_spinlock_t *lock)
+{
+	int tmp = ACCESS_ONCE(lock->slock);
+
+	return (((tmp >> TICKET_SHIFT) - tmp) & ((1 << TICKET_SHIFT) - 1)) + 1;
+}
+
+#define spin_nr_contender(lock) __ticket_spin_nr_contender(&(lock)->raw_lock)
+
 #ifndef CONFIG_PARAVIRT_SPINLOCKS
 
 static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 9ccf0e2..0627706 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -106,6 +106,8 @@ enum bounce_type {
 	bounce_acquired_read,
 	bounce_contended_write,
 	bounce_contended_read,
+	nr_contender,
+	max_contender,
 	nr_bounce_types,
 
 	bounce_acquired = bounce_acquired_write,
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index f0ca7a7..3d86966 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -132,6 +132,10 @@ do {								\
 #endif /*__raw_spin_is_contended*/
 #endif
 
+#ifndef spin_nr_contender
+#define spin_nr_contender(lock) (spin_is_contended(lock) ? 1 : 0)
+#endif
+
 /* The lock does not imply full memory barrier. */
 #ifndef ARCH_HAS_SMP_MB_AFTER_LOCK
 static inline void smp_mb__after_lock(void) { smp_mb(); }
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index f74d2d7..e4b9f80 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -200,8 +200,14 @@ struct lock_class_stats lock_stats(struct lock_class *class)
 		lock_time_add(&pcs->read_holdtime, &stats.read_holdtime);
 		lock_time_add(&pcs->write_holdtime, &stats.write_holdtime);
 
-		for (i = 0; i < ARRAY_SIZE(stats.bounces); i++)
+		for (i = 0; i < ARRAY_SIZE(stats.bounces); i++) {
+			if (i == max_contender) {
+				if (stats.bounces[i] < pcs->bounces[i])
+					stats.bounces[i] = pcs->bounces[i];
+				continue;
+			}
 			stats.bounces[i] += pcs->bounces[i];
+		}
 	}
 
 	return stats;
@@ -3293,9 +3299,15 @@ __lock_contended(struct lockdep_map *lock, unsigned long ip)
 	struct task_struct *curr = current;
 	struct held_lock *hlock, *prev_hlock;
 	struct lock_class_stats *stats;
+	unsigned long contender;
+	spinlock_t *lock_ptr;
 	unsigned int depth;
 	int i, contention_point, contending_point;
 
+	lock_ptr = container_of(lock, spinlock_t, dep_map);
+	if (lock_ptr->magic == SPINLOCK_MAGIC)
+		contender = spin_nr_contender(lock_ptr);
+
 	depth = curr->lockdep_depth;
 	if (DEBUG_LOCKS_WARN_ON(!depth))
 		return;
@@ -3332,6 +3344,13 @@ found_it:
 		stats->contending_point[contending_point]++;
 	if (lock->cpu != smp_processor_id())
 		stats->bounces[bounce_contended + !!hlock->read]++;
+
+	if (lock_ptr->magic == SPINLOCK_MAGIC) {
+		stats->bounces[nr_contender] += contender;
+		if (stats->bounces[max_contender] < contender)
+			stats->bounces[max_contender] = contender;
+	}
+
 	put_lock_stats(stats);
 }
 
diff --git a/kernel/lockdep_proc.c b/kernel/lockdep_proc.c
index d4b3dbc..a3d0910 100644
--- a/kernel/lockdep_proc.c
+++ b/kernel/lockdep_proc.c
@@ -472,6 +472,8 @@ static void seq_stats(struct seq_file *m, struct lock_stat_data *data)
 			seq_printf(m, "%40s:", name);
 
 		seq_printf(m, "%14lu ", stats->bounces[bounce_contended_write]);
+		seq_printf(m, "%14lu ", stats->bounces[nr_contender]);
+		seq_printf(m, "%14lu ", stats->bounces[max_contender]);
 		seq_lock_time(m, &stats->write_waittime);
 		seq_printf(m, " %14lu ", stats->bounces[bounce_acquired_write]);
 		seq_lock_time(m, &stats->write_holdtime);
@@ -541,11 +543,13 @@ static void seq_header(struct seq_file *m)
 	if (unlikely(!debug_locks))
 		seq_printf(m, "*WARNING* lock debugging disabled!! - possibly due to a lockdep warning\n");
 
-	seq_line(m, '-', 0, 40 + 1 + 10 * (14 + 1));
-	seq_printf(m, "%40s %14s %14s %14s %14s %14s %14s %14s %14s "
+	seq_line(m, '-', 0, 40 + 1 + 12 * (14 + 1));
+	seq_printf(m, "%40s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s "
 			"%14s %14s\n",
 			"class name",
 			"con-bounces",
+			"nr-contender",
+			"contender-max",
 			"contentions",
 			"waittime-min",
 			"waittime-max",
-- 
1.6.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ