[PATCH 1/2] add spinlock test to synchro-test module
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
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