sysctl: suppress kmemleak messages
[deliverable/linux.git] / kernel / rcutorture.c
index e66b34ab7555f9153a8c5955678d73fc87b6d777..25b15033c61f88ff7d76854fd16401779d9d9f62 100644 (file)
@@ -49,8 +49,7 @@
 #include <asm/byteorder.h>
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com> and "
-             "Josh Triplett <josh@freedesktop.org>");
+MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com> and Josh Triplett <josh@freedesktop.org>");
 
 static int nreaders = -1;      /* # reader threads, defaults to 2*ncpus */
 static int nfakewriters = 4;   /* # fake writer threads */
@@ -206,6 +205,7 @@ static unsigned long boost_starttime;       /* jiffies of next boost test start. */
 DEFINE_MUTEX(boost_mutex);             /* protect setting boost_starttime */
                                        /*  and boost task create/destroy. */
 static atomic_t barrier_cbs_count;     /* Barrier callbacks registered. */
+static bool barrier_phase;             /* Test phase. */
 static atomic_t barrier_cbs_invoked;   /* Barrier callbacks invoked. */
 static wait_queue_head_t *barrier_cbs_wq; /* Coordinate barrier testing. */
 static DECLARE_WAIT_QUEUE_HEAD(barrier_wq);
@@ -407,8 +407,9 @@ rcu_torture_cb(struct rcu_head *p)
        if (++rp->rtort_pipe_count >= RCU_TORTURE_PIPE_LEN) {
                rp->rtort_mbtest = 0;
                rcu_torture_free(rp);
-       } else
+       } else {
                cur_ops->deferred_free(rp);
+       }
 }
 
 static int rcu_no_completed(void)
@@ -635,6 +636,17 @@ static void srcu_torture_synchronize(void)
        synchronize_srcu(&srcu_ctl);
 }
 
+static void srcu_torture_call(struct rcu_head *head,
+                             void (*func)(struct rcu_head *head))
+{
+       call_srcu(&srcu_ctl, head, func);
+}
+
+static void srcu_torture_barrier(void)
+{
+       srcu_barrier(&srcu_ctl);
+}
+
 static int srcu_torture_stats(char *page)
 {
        int cnt = 0;
@@ -661,8 +673,8 @@ static struct rcu_torture_ops srcu_ops = {
        .completed      = srcu_torture_completed,
        .deferred_free  = srcu_torture_deferred_free,
        .sync           = srcu_torture_synchronize,
-       .call           = NULL,
-       .cb_barrier     = NULL,
+       .call           = srcu_torture_call,
+       .cb_barrier     = srcu_torture_barrier,
        .stats          = srcu_torture_stats,
        .name           = "srcu"
 };
@@ -1013,7 +1025,11 @@ rcu_torture_fakewriter(void *arg)
        do {
                schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10);
                udelay(rcu_random(&rand) & 0x3ff);
-               cur_ops->sync();
+               if (cur_ops->cb_barrier != NULL &&
+                   rcu_random(&rand) % (nfakewriters * 8) == 0)
+                       cur_ops->cb_barrier();
+               else
+                       cur_ops->sync();
                rcu_stutter_wait("rcu_torture_fakewriter");
        } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
 
@@ -1183,27 +1199,27 @@ rcu_torture_printk(char *page)
        }
        cnt += sprintf(&page[cnt], "%s%s ", torture_type, TORTURE_FLAG);
        cnt += sprintf(&page[cnt],
-                      "rtc: %p ver: %lu tfle: %d rta: %d rtaf: %d rtf: %d "
-                      "rtmbe: %d rtbke: %ld rtbre: %ld "
-                      "rtbf: %ld rtb: %ld nt: %ld "
-                      "onoff: %ld/%ld:%ld/%ld "
-                      "barrier: %ld/%ld:%ld",
+                      "rtc: %p ver: %lu tfle: %d rta: %d rtaf: %d rtf: %d ",
                       rcu_torture_current,
                       rcu_torture_current_version,
                       list_empty(&rcu_torture_freelist),
                       atomic_read(&n_rcu_torture_alloc),
                       atomic_read(&n_rcu_torture_alloc_fail),
-                      atomic_read(&n_rcu_torture_free),
+                      atomic_read(&n_rcu_torture_free));
+       cnt += sprintf(&page[cnt], "rtmbe: %d rtbke: %ld rtbre: %ld ",
                       atomic_read(&n_rcu_torture_mberror),
                       n_rcu_torture_boost_ktrerror,
-                      n_rcu_torture_boost_rterror,
+                      n_rcu_torture_boost_rterror);
+       cnt += sprintf(&page[cnt], "rtbf: %ld rtb: %ld nt: %ld ",
                       n_rcu_torture_boost_failure,
                       n_rcu_torture_boosts,
-                      n_rcu_torture_timers,
+                      n_rcu_torture_timers);
+       cnt += sprintf(&page[cnt], "onoff: %ld/%ld:%ld/%ld ",
                       n_online_successes,
                       n_online_attempts,
                       n_offline_successes,
-                      n_offline_attempts,
+                      n_offline_attempts);
+       cnt += sprintf(&page[cnt], "barrier: %ld/%ld:%ld",
                       n_barrier_successes,
                       n_barrier_attempts,
                       n_rcu_torture_barrier_error);
@@ -1445,8 +1461,7 @@ rcu_torture_shutdown(void *arg)
                delta = shutdown_time - jiffies_snap;
                if (verbose)
                        printk(KERN_ALERT "%s" TORTURE_FLAG
-                              "rcu_torture_shutdown task: %lu "
-                              "jiffies remaining\n",
+                              "rcu_torture_shutdown task: %lu jiffies remaining\n",
                               torture_type, delta);
                schedule_timeout_interruptible(delta);
                jiffies_snap = ACCESS_ONCE(jiffies);
@@ -1498,8 +1513,7 @@ rcu_torture_onoff(void *arg)
                        if (cpu_down(cpu) == 0) {
                                if (verbose)
                                        printk(KERN_ALERT "%s" TORTURE_FLAG
-                                              "rcu_torture_onoff task: "
-                                              "offlined %d\n",
+                                              "rcu_torture_onoff task: offlined %d\n",
                                               torture_type, cpu);
                                n_offline_successes++;
                        }
@@ -1512,8 +1526,7 @@ rcu_torture_onoff(void *arg)
                        if (cpu_up(cpu) == 0) {
                                if (verbose)
                                        printk(KERN_ALERT "%s" TORTURE_FLAG
-                                              "rcu_torture_onoff task: "
-                                              "onlined %d\n",
+                                              "rcu_torture_onoff task: onlined %d\n",
                                               torture_type, cpu);
                                n_online_successes++;
                        }
@@ -1631,6 +1644,7 @@ void rcu_torture_barrier_cbf(struct rcu_head *rcu)
 static int rcu_torture_barrier_cbs(void *arg)
 {
        long myid = (long)arg;
+       bool lastphase = 0;
        struct rcu_head rcu;
 
        init_rcu_head_on_stack(&rcu);
@@ -1638,9 +1652,11 @@ static int rcu_torture_barrier_cbs(void *arg)
        set_user_nice(current, 19);
        do {
                wait_event(barrier_cbs_wq[myid],
-                          atomic_read(&barrier_cbs_count) == n_barrier_cbs ||
+                          barrier_phase != lastphase ||
                           kthread_should_stop() ||
                           fullstop != FULLSTOP_DONTSTOP);
+               lastphase = barrier_phase;
+               smp_mb(); /* ensure barrier_phase load before ->call(). */
                if (kthread_should_stop() || fullstop != FULLSTOP_DONTSTOP)
                        break;
                cur_ops->call(&rcu, rcu_torture_barrier_cbf);
@@ -1665,7 +1681,8 @@ static int rcu_torture_barrier(void *arg)
        do {
                atomic_set(&barrier_cbs_invoked, 0);
                atomic_set(&barrier_cbs_count, n_barrier_cbs);
-               /* wake_up() path contains the required barriers. */
+               smp_mb(); /* Ensure barrier_phase after prior assignments. */
+               barrier_phase = !barrier_phase;
                for (i = 0; i < n_barrier_cbs; i++)
                        wake_up(&barrier_cbs_wq[i]);
                wait_event(barrier_wq,
@@ -1684,7 +1701,7 @@ static int rcu_torture_barrier(void *arg)
                schedule_timeout_interruptible(HZ / 10);
        } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
        VERBOSE_PRINTK_STRING("rcu_torture_barrier task stopping");
-       rcutorture_shutdown_absorb("rcu_torture_barrier_cbs");
+       rcutorture_shutdown_absorb("rcu_torture_barrier");
        while (!kthread_should_stop())
                schedule_timeout_interruptible(1);
        return 0;
@@ -1908,8 +1925,8 @@ rcu_torture_init(void)
        static struct rcu_torture_ops *torture_ops[] =
                { &rcu_ops, &rcu_sync_ops, &rcu_expedited_ops,
                  &rcu_bh_ops, &rcu_bh_sync_ops, &rcu_bh_expedited_ops,
-                 &srcu_ops, &srcu_sync_ops, &srcu_raw_ops,
-                 &srcu_raw_sync_ops, &srcu_expedited_ops,
+                 &srcu_ops, &srcu_sync_ops, &srcu_expedited_ops,
+                 &srcu_raw_ops, &srcu_raw_sync_ops,
                  &sched_ops, &sched_sync_ops, &sched_expedited_ops, };
 
        mutex_lock(&fullstop_mutex);
@@ -1931,8 +1948,7 @@ rcu_torture_init(void)
                return -EINVAL;
        }
        if (cur_ops->fqs == NULL && fqs_duration != 0) {
-               printk(KERN_ALERT "rcu-torture: ->fqs NULL and non-zero "
-                                 "fqs_duration, fqs disabled.\n");
+               printk(KERN_ALERT "rcu-torture: ->fqs NULL and non-zero fqs_duration, fqs disabled.\n");
                fqs_duration = 0;
        }
        if (cur_ops->init)
This page took 0.026818 seconds and 5 git commands to generate.