[PATCH 1/2] add spinlock test to synchro-test module

2012-12-30 Thread Michel Lespinasse
Signed-off-by: Michel Lespinasse 

---
 kernel/synchro-test.c |   76 +
 1 files changed, 70 insertions(+), 6 deletions(-)

diff --git a/kernel/synchro-test.c b/kernel/synchro-test.c
index 76e3ad39505f..9abfa955d69e 100644
--- a/kernel/synchro-test.c
+++ b/kernel/synchro-test.c
@@ -41,6 +41,7 @@
 # define VALIDATE_OPERATORS
 #endif
 
+static int numsp;
 static int nummx;
 static int numsm, seminit = 4;
 static int numrd, numwr, numdg;
@@ -54,6 +55,9 @@ MODULE_LICENSE("GPL");
 module_param_named(v, verbose, int, 0);
 MODULE_PARM_DESC(verbose, "Verbosity");
 
+module_param_named(sp, numsp, int, 0);
+MODULE_PARM_DESC(numsp, "Number of spinlock threads");
+
 module_param_named(mx, nummx, int, 0);
 MODULE_PARM_DESC(nummx, "Number of mutex threads");
 
@@ -85,6 +89,7 @@ module_param(do_sched, int, 0);
 MODULE_PARM_DESC(do_sched, "True if each thread should schedule regularly");
 
 /* the semaphores under test */
+static spinlock_t cacheline_aligned spinlock;
 static struct mutex cacheline_aligned mutex;
 static struct semaphore cacheline_aligned sem;
 static struct rw_semaphore cacheline_aligned rwsem;
@@ -92,18 +97,21 @@ static struct rw_semaphore cacheline_aligned rwsem;
 static atomic_t cacheline_aligned do_stuff = ATOMIC_INIT(0);
 
 #ifdef VALIDATE_OPERATORS
+static atomic_t cacheline_aligned spinlocks= 
ATOMIC_INIT(0);
 static atomic_t cacheline_aligned mutexes  = ATOMIC_INIT(0);
 static atomic_t cacheline_aligned semaphores   = ATOMIC_INIT(0);
 static atomic_t cacheline_aligned readers  = ATOMIC_INIT(0);
 static atomic_t cacheline_aligned writers  = ATOMIC_INIT(0);
 #endif
 
+static unsigned int cacheline_aligned spinlocks_taken  [MAX_THREADS];
 static unsigned int cacheline_aligned mutexes_taken
[MAX_THREADS];
 static unsigned int cacheline_aligned semaphores_taken [MAX_THREADS];
 static unsigned int cacheline_aligned reads_taken  [MAX_THREADS];
 static unsigned int cacheline_aligned writes_taken [MAX_THREADS];
 static unsigned int cacheline_aligned downgrades_taken [MAX_THREADS];
 
+static struct completion cacheline_aligned sp_comp[MAX_THREADS];
 static struct completion cacheline_aligned mx_comp[MAX_THREADS];
 static struct completion cacheline_aligned sm_comp[MAX_THREADS];
 static struct completion cacheline_aligned rd_comp[MAX_THREADS];
@@ -130,6 +138,23 @@ do {   
\
 #define CHECK(var, cond, val)  do {} while(0)
 #endif
 
+static inline void do_spin_lock(unsigned int N)
+{
+   spin_lock();
+
+   ACCOUNT(spinlocks, N);
+   TRACK(spinlocks, inc);
+   CHECK(spinlocks, ==, 1);
+}
+
+static inline void do_spin_unlock(unsigned int N)
+{
+   CHECK(spinlocks, ==, 1);
+   TRACK(spinlocks, dec);
+
+   spin_unlock();
+}
+
 static inline void do_mutex_lock(unsigned int N)
 {
mutex_lock();
@@ -221,6 +246,27 @@ static inline void sched(void)
schedule();
 }
 
+static int spinlocker(void *arg)
+{
+   unsigned int N = (unsigned long) arg;
+
+   set_user_nice(current, 19);
+
+   while (atomic_read(_stuff)) {
+   do_spin_lock(N);
+   if (load)
+   udelay(load);
+   do_spin_unlock(N);
+   sched();
+   if (interval)
+   udelay(interval);
+   }
+
+   if (verbose >= 2)
+   printk("%s: done\n", current->comm);
+   complete_and_exit(_comp[N], 0);
+}
+
 static int mutexer(void *arg)
 {
unsigned int N = (unsigned long) arg;
@@ -388,9 +434,11 @@ static unsigned int total(const char *what, unsigned int 
counts[], int num)
 static int __init do_tests(void)
 {
unsigned long loop;
-   unsigned int mutex_total, sem_total, rd_total, wr_total, dg_total;
+   unsigned int spinlock_total, mutex_total, sem_total;
+   unsigned int rd_total, wr_total, dg_total;
 
-   if (nummx < 0 || nummx > MAX_THREADS ||
+   if (numsp < 0 || numsp > MAX_THREADS ||
+   nummx < 0 || nummx > MAX_THREADS ||
numsm < 0 || numsm > MAX_THREADS ||
numrd < 0 || numrd > MAX_THREADS ||
numwr < 0 || numwr > MAX_THREADS ||
@@ -404,12 +452,12 @@ static int __init do_tests(void)
return -ERANGE;
}
 
-   if ((nummx | numsm | numrd | numwr | numdg) == 0) {
+   if ((numsp | nummx | numsm | numrd | numwr | numdg) == 0) {
int num = num_online_cpus();
 
if (num > MAX_THREADS)
num = MAX_THREADS;
-   nummx = numsm = numrd = numwr = numdg = num;
+   numsp = nummx = numsm = numrd = numwr = numdg = num;
 
load = 1;
interval = 1;
@@ -420,6 +468,7 @@ static int __init do_tests(void)
   

[PATCH 1/2] add spinlock test to synchro-test module

2012-12-30 Thread Michel Lespinasse
Signed-off-by: Michel Lespinasse wal...@google.com

---
 kernel/synchro-test.c |   76 +
 1 files changed, 70 insertions(+), 6 deletions(-)

diff --git a/kernel/synchro-test.c b/kernel/synchro-test.c
index 76e3ad39505f..9abfa955d69e 100644
--- a/kernel/synchro-test.c
+++ b/kernel/synchro-test.c
@@ -41,6 +41,7 @@
 # define VALIDATE_OPERATORS
 #endif
 
+static int numsp;
 static int nummx;
 static int numsm, seminit = 4;
 static int numrd, numwr, numdg;
@@ -54,6 +55,9 @@ MODULE_LICENSE(GPL);
 module_param_named(v, verbose, int, 0);
 MODULE_PARM_DESC(verbose, Verbosity);
 
+module_param_named(sp, numsp, int, 0);
+MODULE_PARM_DESC(numsp, Number of spinlock threads);
+
 module_param_named(mx, nummx, int, 0);
 MODULE_PARM_DESC(nummx, Number of mutex threads);
 
@@ -85,6 +89,7 @@ module_param(do_sched, int, 0);
 MODULE_PARM_DESC(do_sched, True if each thread should schedule regularly);
 
 /* the semaphores under test */
+static spinlock_t cacheline_aligned spinlock;
 static struct mutex cacheline_aligned mutex;
 static struct semaphore cacheline_aligned sem;
 static struct rw_semaphore cacheline_aligned rwsem;
@@ -92,18 +97,21 @@ static struct rw_semaphore cacheline_aligned rwsem;
 static atomic_t cacheline_aligned do_stuff = ATOMIC_INIT(0);
 
 #ifdef VALIDATE_OPERATORS
+static atomic_t cacheline_aligned spinlocks= 
ATOMIC_INIT(0);
 static atomic_t cacheline_aligned mutexes  = ATOMIC_INIT(0);
 static atomic_t cacheline_aligned semaphores   = ATOMIC_INIT(0);
 static atomic_t cacheline_aligned readers  = ATOMIC_INIT(0);
 static atomic_t cacheline_aligned writers  = ATOMIC_INIT(0);
 #endif
 
+static unsigned int cacheline_aligned spinlocks_taken  [MAX_THREADS];
 static unsigned int cacheline_aligned mutexes_taken
[MAX_THREADS];
 static unsigned int cacheline_aligned semaphores_taken [MAX_THREADS];
 static unsigned int cacheline_aligned reads_taken  [MAX_THREADS];
 static unsigned int cacheline_aligned writes_taken [MAX_THREADS];
 static unsigned int cacheline_aligned downgrades_taken [MAX_THREADS];
 
+static struct completion cacheline_aligned sp_comp[MAX_THREADS];
 static struct completion cacheline_aligned mx_comp[MAX_THREADS];
 static struct completion cacheline_aligned sm_comp[MAX_THREADS];
 static struct completion cacheline_aligned rd_comp[MAX_THREADS];
@@ -130,6 +138,23 @@ do {   
\
 #define CHECK(var, cond, val)  do {} while(0)
 #endif
 
+static inline void do_spin_lock(unsigned int N)
+{
+   spin_lock(spinlock);
+
+   ACCOUNT(spinlocks, N);
+   TRACK(spinlocks, inc);
+   CHECK(spinlocks, ==, 1);
+}
+
+static inline void do_spin_unlock(unsigned int N)
+{
+   CHECK(spinlocks, ==, 1);
+   TRACK(spinlocks, dec);
+
+   spin_unlock(spinlock);
+}
+
 static inline void do_mutex_lock(unsigned int N)
 {
mutex_lock(mutex);
@@ -221,6 +246,27 @@ static inline void sched(void)
schedule();
 }
 
+static int spinlocker(void *arg)
+{
+   unsigned int N = (unsigned long) arg;
+
+   set_user_nice(current, 19);
+
+   while (atomic_read(do_stuff)) {
+   do_spin_lock(N);
+   if (load)
+   udelay(load);
+   do_spin_unlock(N);
+   sched();
+   if (interval)
+   udelay(interval);
+   }
+
+   if (verbose = 2)
+   printk(%s: done\n, current-comm);
+   complete_and_exit(sp_comp[N], 0);
+}
+
 static int mutexer(void *arg)
 {
unsigned int N = (unsigned long) arg;
@@ -388,9 +434,11 @@ static unsigned int total(const char *what, unsigned int 
counts[], int num)
 static int __init do_tests(void)
 {
unsigned long loop;
-   unsigned int mutex_total, sem_total, rd_total, wr_total, dg_total;
+   unsigned int spinlock_total, mutex_total, sem_total;
+   unsigned int rd_total, wr_total, dg_total;
 
-   if (nummx  0 || nummx  MAX_THREADS ||
+   if (numsp  0 || numsp  MAX_THREADS ||
+   nummx  0 || nummx  MAX_THREADS ||
numsm  0 || numsm  MAX_THREADS ||
numrd  0 || numrd  MAX_THREADS ||
numwr  0 || numwr  MAX_THREADS ||
@@ -404,12 +452,12 @@ static int __init do_tests(void)
return -ERANGE;
}
 
-   if ((nummx | numsm | numrd | numwr | numdg) == 0) {
+   if ((numsp | nummx | numsm | numrd | numwr | numdg) == 0) {
int num = num_online_cpus();
 
if (num  MAX_THREADS)
num = MAX_THREADS;
-   nummx = numsm = numrd = numwr = numdg = num;
+   numsp = nummx = numsm = numrd = numwr = numdg = num;
 
load = 1;
interval = 1;
@@ -420,6 +468,7 @@ static int __init