Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1576817 > unrolled thread

[PATCH 00/10] sched.h modernization -v2, phase #1: "Pre-splitup cleanups"

Started byIngo Molnar <mingo@kernel.org>
First post2017-02-08 19:40 +0100
Last post2017-02-08 21:30 +0100
Articles 12 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 00/10] sched.h modernization -v2, phase #1: "Pre-splitup cleanups" Ingo Molnar <mingo@kernel.org> - 2017-02-08 19:40 +0100
    [PATCH 06/10] sched/core: Remove the tsk_nr_cpus_allowed() wrapper Ingo Molnar <mingo@kernel.org> - 2017-02-08 19:40 +0100
    [PATCH 01/10] sched/headers: Make all include/linux/sched/*.h headers build standalone Ingo Molnar <mingo@kernel.org> - 2017-02-08 19:40 +0100
    [PATCH 03/10] sched/headers: Make task_struct::wake_q an opaque pointer Ingo Molnar <mingo@kernel.org> - 2017-02-08 19:40 +0100
      Re: [PATCH 03/10] sched/headers: Make task_struct::wake_q an opaque pointer Linus Torvalds <torvalds@linux-foundation.org> - 2017-02-08 21:10 +0100
        [PATCH] sched/wake_q: Restore task_struct::wake_q type safety Ingo Molnar <mingo@kernel.org> - 2017-02-08 22:40 +0100
    [PATCH 08/10] sched/headers, cgroups: Remove the threadgroup_change_*() wrappery Ingo Molnar <mingo@kernel.org> - 2017-02-08 19:50 +0100
    [PATCH 10/10] kasan, sched/headers: Uninline kasan_enable/disable_current() Ingo Molnar <mingo@kernel.org> - 2017-02-08 20:10 +0100
    [PATCH 09/10] mm/vmacache, sched/headers: Introduce 'struct vmacache' and move it from <linux/sched.h> to <linux/mm_types> Ingo Molnar <mingo@kernel.org> - 2017-02-08 20:50 +0100
    [PATCH 07/10] rcu: Separate the RCU synchronization types and APIs into <linux/rcupdate_wait.h> Ingo Molnar <mingo@kernel.org> - 2017-02-08 20:50 +0100
      Re: [PATCH 07/10] rcu: Separate the RCU synchronization types and  APIs into <linux/rcupdate_wait.h> Paul McKenney <paulmckrcu@gmail.com> - 2017-02-11 20:20 +0100
    Re: [PATCH 00/10] sched.h modernization -v2, phase #1: "Pre-splitup cleanups" Linus Torvalds <torvalds@linux-foundation.org> - 2017-02-08 21:30 +0100

#1576817 — [PATCH 00/10] sched.h modernization -v2, phase #1: "Pre-splitup cleanups"

FromIngo Molnar <mingo@kernel.org>
Date2017-02-08 19:40 +0100
Subject[PATCH 00/10] sched.h modernization -v2, phase #1: "Pre-splitup cleanups"
Message-ID<t8FjQ-3Oi-11@gated-at.bofh.it>
This is the second version of the sched.h modernization series I posted two days
ago:

  https://lkml.org/lkml/2017/2/6/468

The point of the series is to significantly reduce the <linux/sched.h> footprint,
to speed up the kernel build and to have a cleaner header structure. The new
<linux/sched.h>'s typical preprocessed size goes down from ~0.68 MB (~22K lines)
to ~0.45 MB (~15K lines) and is around 40% faster to build on typical configs.

The Git tree can be found at:

     git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git WIP.sched/core

Changes in -v2:

As per the suggestions from Linus, -v2 has a reworked patch split-up structure
that should be easier to review, validate, test and bisect. I've further
split up the patches into 148 component patches and reordered them into the
following five groups/phases:

  phase #1: "Pre-splitup cleanups":               # 0721da143d99~1..582c7529a1bd,   10 patches

  phase #2: "Prepare header dependencies":        # 9017f600c534~1..d1eb6f0b580d,   48 patches
  phase #3: "Move definitions between headers":   # 3d01f4b6e32d~1..fd88c1773dd6,   53 patches
  phase #4: "Remove header dependencies":         # 2d246f83c5d3~1..2205323e0ca1,   35 patches

  phase #5: "Post-splitup cleanups":              # 55cf8bfb3af4~1..bcc6be9d66b2,    2 patches

The "pre-splitup cleanups" phase does a handful of preparatory changes that make
the subsequent sched.h restructuring easier. Some of these patches have (mostly
minor) semantic side-effects.

The middle phases are structured in a way to make it relatively easy to review
and verify that they have no semantic side-effects:

  "Prepare header dependencies":

  - These patches just add trivial placeholder headers and update various .c and .h
    files with the expected future dependencies. These patches increase the header
    dependency graph of the kernel monotonically.

  "Move definitions between headers":

  - These are the meat of the code movement, but they don't actually change the header
    dependency graph: all code movement is between pre-existing headers.

  "Remove header dependencies":

  - These remove header #include lines and remove prototypes and thus shrink the
    header dependency graph monotonically to the desired end result. These are
    small patches but most breakage will likely bisect to these, so their
    finegrained split-up is useful as well.

The "post-splitup cleanups" do cleanups on top of the finished split-up header
structure. It's two patches for now, more cleanups will be done later.

I've done a bisection step by step build test of all 148 steps on x86-defconfig,
and have performed a fair amount of all[yes|mod|no]config tests, cross-build tests
and boot tests on the final tree. Fixes to any bugs will be merged back into the
series to preserve bisectability.

As a first step the "pre-splitup" patches are sent a reply to this 0/10 email.

I'll send the other phases in separate email threads, to make them easier to
review.

As usual, any feedback is welcome!

Thanks,

	Ingo

Ingo Molnar (10):
  sched/headers: Make all include/linux/sched/*.h headers build standalone
  sched/core: Convert ___assert_task_state() link time assert to BUILD_BUG_ON()
  sched/headers: Make task_struct::wake_q an opaque pointer
  sched/core: Move the get_preempt_disable_ip() inline to sched/core.c
  sched/core: Remove the tsk_cpus_allowed() wrapper
  sched/core: Remove the tsk_nr_cpus_allowed() wrapper
  rcu: Separate the RCU synchronization types and APIs into <linux/rcupdate_wait.h>
  sched/headers, cgroups: Remove the threadgroup_change_*() wrappery
  mm/vmacache, sched/headers: Introduce 'struct vmacache' and move it from <linux/sched.h> to <linux/mm_types>
  kasan, sched/headers: Uninline kasan_enable/disable_current()

 arch/powerpc/kernel/smp.c                  |  2 +-
 arch/powerpc/platforms/cell/spufs/sched.c  |  2 +-
 arch/sparc/kernel/sysfs.c                  |  2 +-
 drivers/cpufreq/sparc-us2e-cpufreq.c       |  4 ++--
 drivers/cpufreq/sparc-us3-cpufreq.c        |  4 ++--
 drivers/infiniband/hw/hfi1/affinity.c      |  2 +-
 drivers/infiniband/hw/hfi1/sdma.c          |  2 +-
 fs/autofs4/autofs_i.h                      |  1 +
 fs/exec.c                                  |  6 ++---
 include/linux/cgroup-defs.h                | 13 ++++++-----
 include/linux/dcache.h                     |  1 +
 include/linux/kasan.h                      | 10 ++-------
 include/linux/mm_types.h                   | 12 ++++++++++
 include/linux/rcupdate.h                   | 40 ---------------------------------
 include/linux/rcupdate_wait.h              | 50 +++++++++++++++++++++++++++++++++++++++++
 include/linux/rcutiny.h                    | 11 ++-------
 include/linux/sched.h                      | 61 +++++---------------------------------------------
 include/linux/sched/deadline.h             |  8 ++++---
 include/linux/sched/prio.h                 |  6 ++---
 include/linux/sched/rt.h                   | 10 +++++----
 include/linux/sched/sysctl.h               | 10 ++++++---
 include/linux/vmacache.h                   |  2 +-
 kernel/cgroup_pids.c                       |  2 +-
 kernel/debug/debug_core.c                  |  4 ++--
 kernel/fork.c                              |  8 +++----
 kernel/rcu/srcu.c                          |  2 +-
 kernel/rcu/tiny.c                          | 14 +++++++++++-
 kernel/rcu/tree.c                          |  2 +-
 kernel/rcu/update.c                        |  1 +
 kernel/sched/core.c                        | 41 +++++++++++++++++++++------------
 kernel/sched/cpudeadline.c                 |  4 ++--
 kernel/sched/cpupri.c                      |  4 ++--
 kernel/sched/deadline.c                    | 35 ++++++++++++++---------------
 kernel/sched/fair.c                        | 25 ++++++++++-----------
 kernel/sched/rt.c                          | 29 ++++++++++++------------
 kernel/signal.c                            |  6 ++---
 lib/sbitmap.c                              |  1 +
 lib/smp_processor_id.c                     |  2 +-
 mm/kasan/kasan.c                           | 10 +++++++++
 mm/nommu.c                                 |  2 +-
 mm/vmacache.c                              | 10 ++++-----
 samples/trace_events/trace-events-sample.c |  2 +-
 42 files changed, 234 insertions(+), 229 deletions(-)
 create mode 100644 include/linux/rcupdate_wait.h

-- 
2.7.4

[toc] | [next] | [standalone]


#1576818 — [PATCH 06/10] sched/core: Remove the tsk_nr_cpus_allowed() wrapper

FromIngo Molnar <mingo@kernel.org>
Date2017-02-08 19:40 +0100
Subject[PATCH 06/10] sched/core: Remove the tsk_nr_cpus_allowed() wrapper
Message-ID<t8FjQ-3Oi-25@gated-at.bofh.it>
In reply to#1576817
tsk_nr_cpus_allowed() too is a pretty pointless wrapper that
is not used consistently and which makes the code both harder
to read and longer as well.

So remove it - this also shrinks <linux/sched.h> a bit.

Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 include/linux/sched.h   |  5 -----
 kernel/sched/core.c     |  2 +-
 kernel/sched/deadline.c | 28 ++++++++++++++--------------
 kernel/sched/rt.c       | 24 ++++++++++++------------
 4 files changed, 27 insertions(+), 32 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 38af022b351d..4e2e738e2c61 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1999,11 +1999,6 @@ static inline struct vm_struct *task_stack_vm_area(const struct task_struct *t)
 }
 #endif
 
-static inline int tsk_nr_cpus_allowed(struct task_struct *p)
-{
-	return p->nr_cpus_allowed;
-}
-
 #define TNF_MIGRATED	0x01
 #define TNF_NO_GROUP	0x02
 #define TNF_SHARED	0x04
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 0706863f83b5..258af6d00682 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -1545,7 +1545,7 @@ int select_task_rq(struct task_struct *p, int cpu, int sd_flags, int wake_flags)
 {
 	lockdep_assert_held(&p->pi_lock);
 
-	if (tsk_nr_cpus_allowed(p) > 1)
+	if (p->nr_cpus_allowed > 1)
 		cpu = p->sched_class->select_task_rq(p, cpu, sd_flags, wake_flags);
 	else
 		cpu = cpumask_any(&p->cpus_allowed);
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index 8e4d6e4e3ccc..99b2c33a9fbc 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -134,7 +134,7 @@ static void inc_dl_migration(struct sched_dl_entity *dl_se, struct dl_rq *dl_rq)
 {
 	struct task_struct *p = dl_task_of(dl_se);
 
-	if (tsk_nr_cpus_allowed(p) > 1)
+	if (p->nr_cpus_allowed > 1)
 		dl_rq->dl_nr_migratory++;
 
 	update_dl_migration(dl_rq);
@@ -144,7 +144,7 @@ static void dec_dl_migration(struct sched_dl_entity *dl_se, struct dl_rq *dl_rq)
 {
 	struct task_struct *p = dl_task_of(dl_se);
 
-	if (tsk_nr_cpus_allowed(p) > 1)
+	if (p->nr_cpus_allowed > 1)
 		dl_rq->dl_nr_migratory--;
 
 	update_dl_migration(dl_rq);
@@ -958,7 +958,7 @@ static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags)
 
 	enqueue_dl_entity(&p->dl, pi_se, flags);
 
-	if (!task_current(rq, p) && tsk_nr_cpus_allowed(p) > 1)
+	if (!task_current(rq, p) && p->nr_cpus_allowed > 1)
 		enqueue_pushable_dl_task(rq, p);
 }
 
@@ -1032,9 +1032,9 @@ select_task_rq_dl(struct task_struct *p, int cpu, int sd_flag, int flags)
 	 * try to make it stay here, it might be important.
 	 */
 	if (unlikely(dl_task(curr)) &&
-	    (tsk_nr_cpus_allowed(curr) < 2 ||
+	    (curr->nr_cpus_allowed < 2 ||
 	     !dl_entity_preempt(&p->dl, &curr->dl)) &&
-	    (tsk_nr_cpus_allowed(p) > 1)) {
+	    (p->nr_cpus_allowed > 1)) {
 		int target = find_later_rq(p);
 
 		if (target != -1 &&
@@ -1055,7 +1055,7 @@ static void check_preempt_equal_dl(struct rq *rq, struct task_struct *p)
 	 * Current can't be migrated, useless to reschedule,
 	 * let's hope p can move out.
 	 */
-	if (tsk_nr_cpus_allowed(rq->curr) == 1 ||
+	if (rq->curr->nr_cpus_allowed == 1 ||
 	    cpudl_find(&rq->rd->cpudl, rq->curr, NULL) == -1)
 		return;
 
@@ -1063,7 +1063,7 @@ static void check_preempt_equal_dl(struct rq *rq, struct task_struct *p)
 	 * p is migratable, so let's not schedule it and
 	 * see if it is pushed or pulled somewhere else.
 	 */
-	if (tsk_nr_cpus_allowed(p) != 1 &&
+	if (p->nr_cpus_allowed != 1 &&
 	    cpudl_find(&rq->rd->cpudl, p, NULL) != -1)
 		return;
 
@@ -1178,7 +1178,7 @@ static void put_prev_task_dl(struct rq *rq, struct task_struct *p)
 {
 	update_curr_dl(rq);
 
-	if (on_dl_rq(&p->dl) && tsk_nr_cpus_allowed(p) > 1)
+	if (on_dl_rq(&p->dl) && p->nr_cpus_allowed > 1)
 		enqueue_pushable_dl_task(rq, p);
 }
 
@@ -1279,7 +1279,7 @@ static int find_later_rq(struct task_struct *task)
 	if (unlikely(!later_mask))
 		return -1;
 
-	if (tsk_nr_cpus_allowed(task) == 1)
+	if (task->nr_cpus_allowed == 1)
 		return -1;
 
 	/*
@@ -1424,7 +1424,7 @@ static struct task_struct *pick_next_pushable_dl_task(struct rq *rq)
 
 	BUG_ON(rq->cpu != task_cpu(p));
 	BUG_ON(task_current(rq, p));
-	BUG_ON(tsk_nr_cpus_allowed(p) <= 1);
+	BUG_ON(p->nr_cpus_allowed <= 1);
 
 	BUG_ON(!task_on_rq_queued(p));
 	BUG_ON(!dl_task(p));
@@ -1463,7 +1463,7 @@ static int push_dl_task(struct rq *rq)
 	 */
 	if (dl_task(rq->curr) &&
 	    dl_time_before(next_task->dl.deadline, rq->curr->dl.deadline) &&
-	    tsk_nr_cpus_allowed(rq->curr) > 1) {
+	    rq->curr->nr_cpus_allowed > 1) {
 		resched_curr(rq);
 		return 0;
 	}
@@ -1610,9 +1610,9 @@ static void task_woken_dl(struct rq *rq, struct task_struct *p)
 {
 	if (!task_running(rq, p) &&
 	    !test_tsk_need_resched(rq->curr) &&
-	    tsk_nr_cpus_allowed(p) > 1 &&
+	    p->nr_cpus_allowed > 1 &&
 	    dl_task(rq->curr) &&
-	    (tsk_nr_cpus_allowed(rq->curr) < 2 ||
+	    (rq->curr->nr_cpus_allowed < 2 ||
 	     !dl_entity_preempt(&p->dl, &rq->curr->dl))) {
 		push_dl_tasks(rq);
 	}
@@ -1726,7 +1726,7 @@ static void switched_to_dl(struct rq *rq, struct task_struct *p)
 
 	if (rq->curr != p) {
 #ifdef CONFIG_SMP
-		if (tsk_nr_cpus_allowed(p) > 1 && rq->dl.overloaded)
+		if (p->nr_cpus_allowed > 1 && rq->dl.overloaded)
 			queue_push_tasks(rq);
 #endif
 		if (dl_task(rq->curr))
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index cbd356f63883..9f3e40226dec 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -335,7 +335,7 @@ static void inc_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
 	rt_rq = &rq_of_rt_rq(rt_rq)->rt;
 
 	rt_rq->rt_nr_total++;
-	if (tsk_nr_cpus_allowed(p) > 1)
+	if (p->nr_cpus_allowed > 1)
 		rt_rq->rt_nr_migratory++;
 
 	update_rt_migration(rt_rq);
@@ -352,7 +352,7 @@ static void dec_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
 	rt_rq = &rq_of_rt_rq(rt_rq)->rt;
 
 	rt_rq->rt_nr_total--;
-	if (tsk_nr_cpus_allowed(p) > 1)
+	if (p->nr_cpus_allowed > 1)
 		rt_rq->rt_nr_migratory--;
 
 	update_rt_migration(rt_rq);
@@ -1324,7 +1324,7 @@ enqueue_task_rt(struct rq *rq, struct task_struct *p, int flags)
 
 	enqueue_rt_entity(rt_se, flags);
 
-	if (!task_current(rq, p) && tsk_nr_cpus_allowed(p) > 1)
+	if (!task_current(rq, p) && p->nr_cpus_allowed > 1)
 		enqueue_pushable_task(rq, p);
 }
 
@@ -1413,7 +1413,7 @@ select_task_rq_rt(struct task_struct *p, int cpu, int sd_flag, int flags)
 	 * will have to sort it out.
 	 */
 	if (curr && unlikely(rt_task(curr)) &&
-	    (tsk_nr_cpus_allowed(curr) < 2 ||
+	    (curr->nr_cpus_allowed < 2 ||
 	     curr->prio <= p->prio)) {
 		int target = find_lowest_rq(p);
 
@@ -1437,7 +1437,7 @@ static void check_preempt_equal_prio(struct rq *rq, struct task_struct *p)
 	 * Current can't be migrated, useless to reschedule,
 	 * let's hope p can move out.
 	 */
-	if (tsk_nr_cpus_allowed(rq->curr) == 1 ||
+	if (rq->curr->nr_cpus_allowed == 1 ||
 	    !cpupri_find(&rq->rd->cpupri, rq->curr, NULL))
 		return;
 
@@ -1445,7 +1445,7 @@ static void check_preempt_equal_prio(struct rq *rq, struct task_struct *p)
 	 * p is migratable, so let's not schedule it and
 	 * see if it is pushed or pulled somewhere else.
 	 */
-	if (tsk_nr_cpus_allowed(p) != 1
+	if (p->nr_cpus_allowed != 1
 	    && cpupri_find(&rq->rd->cpupri, p, NULL))
 		return;
 
@@ -1579,7 +1579,7 @@ static void put_prev_task_rt(struct rq *rq, struct task_struct *p)
 	 * The previous task needs to be made eligible for pushing
 	 * if it is still active
 	 */
-	if (on_rt_rq(&p->rt) && tsk_nr_cpus_allowed(p) > 1)
+	if (on_rt_rq(&p->rt) && p->nr_cpus_allowed > 1)
 		enqueue_pushable_task(rq, p);
 }
 
@@ -1629,7 +1629,7 @@ static int find_lowest_rq(struct task_struct *task)
 	if (unlikely(!lowest_mask))
 		return -1;
 
-	if (tsk_nr_cpus_allowed(task) == 1)
+	if (task->nr_cpus_allowed == 1)
 		return -1; /* No other targets possible */
 
 	if (!cpupri_find(&task_rq(task)->rd->cpupri, task, lowest_mask))
@@ -1761,7 +1761,7 @@ static struct task_struct *pick_next_pushable_task(struct rq *rq)
 
 	BUG_ON(rq->cpu != task_cpu(p));
 	BUG_ON(task_current(rq, p));
-	BUG_ON(tsk_nr_cpus_allowed(p) <= 1);
+	BUG_ON(p->nr_cpus_allowed <= 1);
 
 	BUG_ON(!task_on_rq_queued(p));
 	BUG_ON(!rt_task(p));
@@ -2121,9 +2121,9 @@ static void task_woken_rt(struct rq *rq, struct task_struct *p)
 {
 	if (!task_running(rq, p) &&
 	    !test_tsk_need_resched(rq->curr) &&
-	    tsk_nr_cpus_allowed(p) > 1 &&
+	    p->nr_cpus_allowed > 1 &&
 	    (dl_task(rq->curr) || rt_task(rq->curr)) &&
-	    (tsk_nr_cpus_allowed(rq->curr) < 2 ||
+	    (rq->curr->nr_cpus_allowed < 2 ||
 	     rq->curr->prio <= p->prio))
 		push_rt_tasks(rq);
 }
@@ -2196,7 +2196,7 @@ static void switched_to_rt(struct rq *rq, struct task_struct *p)
 	 */
 	if (task_on_rq_queued(p) && rq->curr != p) {
 #ifdef CONFIG_SMP
-		if (tsk_nr_cpus_allowed(p) > 1 && rq->rt.overloaded)
+		if (p->nr_cpus_allowed > 1 && rq->rt.overloaded)
 			queue_push_tasks(rq);
 #endif /* CONFIG_SMP */
 		if (p->prio < rq->curr->prio)
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1576821 — [PATCH 01/10] sched/headers: Make all include/linux/sched/*.h headers build standalone

FromIngo Molnar <mingo@kernel.org>
Date2017-02-08 19:40 +0100
Subject[PATCH 01/10] sched/headers: Make all include/linux/sched/*.h headers build standalone
Message-ID<t8FjR-3Oi-29@gated-at.bofh.it>
In reply to#1576817
Make each header self-sufficient, so that it can be built successfully
both in an allnoconfig and allyesconfig kernel.

Also standardize the naming of their header guards.

Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 include/linux/sched/deadline.h |  8 +++++---
 include/linux/sched/prio.h     |  6 +++---
 include/linux/sched/rt.h       | 10 ++++++----
 include/linux/sched/sysctl.h   | 10 +++++++---
 4 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/include/linux/sched/deadline.h b/include/linux/sched/deadline.h
index 9089a2ae913d..975be862e083 100644
--- a/include/linux/sched/deadline.h
+++ b/include/linux/sched/deadline.h
@@ -1,5 +1,7 @@
-#ifndef _SCHED_DEADLINE_H
-#define _SCHED_DEADLINE_H
+#ifndef _LINUX_SCHED_DEADLINE_H
+#define _LINUX_SCHED_DEADLINE_H
+
+#include <linux/sched.h>
 
 /*
  * SCHED_DEADLINE tasks has negative priorities, reflecting
@@ -26,4 +28,4 @@ static inline bool dl_time_before(u64 a, u64 b)
 	return (s64)(a - b) < 0;
 }
 
-#endif /* _SCHED_DEADLINE_H */
+#endif /* _LINUX_SCHED_DEADLINE_H */
diff --git a/include/linux/sched/prio.h b/include/linux/sched/prio.h
index d9cf5a5762d9..2cc450f6ec54 100644
--- a/include/linux/sched/prio.h
+++ b/include/linux/sched/prio.h
@@ -1,5 +1,5 @@
-#ifndef _SCHED_PRIO_H
-#define _SCHED_PRIO_H
+#ifndef _LINUX_SCHED_PRIO_H
+#define _LINUX_SCHED_PRIO_H
 
 #define MAX_NICE	19
 #define MIN_NICE	-20
@@ -57,4 +57,4 @@ static inline long rlimit_to_nice(long prio)
 	return (MAX_NICE - prio + 1);
 }
 
-#endif /* _SCHED_PRIO_H */
+#endif /* _LINUX_SCHED_PRIO_H */
diff --git a/include/linux/sched/rt.h b/include/linux/sched/rt.h
index a30b172df6e1..3bd668414f61 100644
--- a/include/linux/sched/rt.h
+++ b/include/linux/sched/rt.h
@@ -1,7 +1,9 @@
-#ifndef _SCHED_RT_H
-#define _SCHED_RT_H
+#ifndef _LINUX_SCHED_RT_H
+#define _LINUX_SCHED_RT_H
 
-#include <linux/sched/prio.h>
+#include <linux/sched.h>
+
+struct task_struct;
 
 static inline int rt_prio(int prio)
 {
@@ -57,4 +59,4 @@ extern void normalize_rt_tasks(void);
  */
 #define RR_TIMESLICE		(100 * HZ / 1000)
 
-#endif /* _SCHED_RT_H */
+#endif /* _LINUX_SCHED_RT_H */
diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h
index 49308e142aae..0f5ecd4d298e 100644
--- a/include/linux/sched/sysctl.h
+++ b/include/linux/sched/sysctl.h
@@ -1,5 +1,9 @@
-#ifndef _SCHED_SYSCTL_H
-#define _SCHED_SYSCTL_H
+#ifndef _LINUX_SCHED_SYSCTL_H
+#define _LINUX_SCHED_SYSCTL_H
+
+#include <linux/types.h>
+
+struct ctl_table;
 
 #ifdef CONFIG_DETECT_HUNG_TASK
 extern int	     sysctl_hung_task_check_count;
@@ -78,4 +82,4 @@ extern int sysctl_schedstats(struct ctl_table *table, int write,
 				 void __user *buffer, size_t *lenp,
 				 loff_t *ppos);
 
-#endif /* _SCHED_SYSCTL_H */
+#endif /* _LINUX_SCHED_SYSCTL_H */
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1576822 — [PATCH 03/10] sched/headers: Make task_struct::wake_q an opaque pointer

FromIngo Molnar <mingo@kernel.org>
Date2017-02-08 19:40 +0100
Subject[PATCH 03/10] sched/headers: Make task_struct::wake_q an opaque pointer
Message-ID<t8FjQ-3Oi-23@gated-at.bofh.it>
In reply to#1576817
To be able to decouple wake_q functionality from <linux/sched.h> make
the basic task_struct::wake_q pointer an opaque void *.

Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 include/linux/sched.h | 2 +-
 kernel/fork.c         | 2 +-
 kernel/sched/core.c   | 6 +++---
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 54651e828ac4..255780f95de1 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1725,7 +1725,7 @@ struct task_struct {
 	/* Protection of the PI data structures: */
 	raw_spinlock_t pi_lock;
 
-	struct wake_q_node wake_q;
+	void *wake_q;
 
 #ifdef CONFIG_RT_MUTEXES
 	/* PI waiters blocked on a rt_mutex held by this task */
diff --git a/kernel/fork.c b/kernel/fork.c
index 077ce3b4c0ef..9aa2ca28a76c 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -538,7 +538,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
 #endif
 	tsk->splice_pipe = NULL;
 	tsk->task_frag.page = NULL;
-	tsk->wake_q.next = NULL;
+	tsk->wake_q = NULL;
 
 	account_kernel_stack(tsk, 1);
 
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 675647b0b84b..c4cebf6628de 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -426,7 +426,7 @@ static bool set_nr_if_polling(struct task_struct *p)
 
 void wake_q_add(struct wake_q_head *head, struct task_struct *task)
 {
-	struct wake_q_node *node = &task->wake_q;
+	struct wake_q_node *node = (void *)&task->wake_q;
 
 	/*
 	 * Atomically grab the task, if ->wake_q is !nil already it means
@@ -455,11 +455,11 @@ void wake_up_q(struct wake_q_head *head)
 	while (node != WAKE_Q_TAIL) {
 		struct task_struct *task;
 
-		task = container_of(node, struct task_struct, wake_q);
+		task = container_of((void *)node, struct task_struct, wake_q);
 		BUG_ON(!task);
 		/* Task can safely be re-inserted now: */
 		node = node->next;
-		task->wake_q.next = NULL;
+		task->wake_q = NULL;
 
 		/*
 		 * wake_up_process() implies a wmb() to pair with the queueing
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1577009 — Re: [PATCH 03/10] sched/headers: Make task_struct::wake_q an opaque pointer

FromLinus Torvalds <torvalds@linux-foundation.org>
Date2017-02-08 21:10 +0100
SubjectRe: [PATCH 03/10] sched/headers: Make task_struct::wake_q an opaque pointer
Message-ID<t8GIV-4OC-11@gated-at.bofh.it>
In reply to#1576822
On Wed, Feb 8, 2017 at 10:34 AM, Ingo Molnar <mingo@kernel.org> wrote:
> To be able to decouple wake_q functionality from <linux/sched.h> make
> the basic task_struct::wake_q pointer an opaque void *.

Please don't use "void *" for opaque pointers.

You lose all typechecking, and this is just complete garbage:

+       struct wake_q_node *node = (void *)&task->wake_q;

What? You're casting a "void *" to "void *"? WTF?

The proper way to do opaque pointers is to declare them as pointers to
a structure that hasn't been defined (ie use a "struct xyz;" forward
declaration), and then that structure is only actually defined in the
places that use the otherwise opaque pointer.

That way you

 (a) never need to cast anything

 (b) get proper (and strong) type checking for the pointers.

and the people who need to look into it automatically do the right
thing, while anybody else who tries to dereference or otherwise use
the struct pointer will get a compiler error.

               Linus

[toc] | [prev] | [next] | [standalone]


#1577115 — [PATCH] sched/wake_q: Restore task_struct::wake_q type safety

FromIngo Molnar <mingo@kernel.org>
Date2017-02-08 22:40 +0100
Subject[PATCH] sched/wake_q: Restore task_struct::wake_q type safety
Message-ID<t8I84-5Aj-59@gated-at.bofh.it>
In reply to#1577009
* Linus Torvalds <torvalds@linux-foundation.org> wrote:

> On Wed, Feb 8, 2017 at 10:34 AM, Ingo Molnar <mingo@kernel.org> wrote:
> > To be able to decouple wake_q functionality from <linux/sched.h> make
> > the basic task_struct::wake_q pointer an opaque void *.
> 
> Please don't use "void *" for opaque pointers.
> 
> You lose all typechecking, and this is just complete garbage:
> 
> +       struct wake_q_node *node = (void *)&task->wake_q;
> 
> What? You're casting a "void *" to "void *"? WTF?

Well, I'm casting 'void **' to 'void *', so the cast is necessary in this specific 
scheme - but yeah, this is still pretty ugly.

> The proper way to do opaque pointers is to declare them as pointers to
> a structure that hasn't been defined (ie use a "struct xyz;" forward
> declaration), and then that structure is only actually defined in the
> places that use the otherwise opaque pointer.
> 
> That way you
> 
>  (a) never need to cast anything
> 
>  (b) get proper (and strong) type checking for the pointers.
> 
> and the people who need to look into it automatically do the right
> thing, while anybody else who tries to dereference or otherwise use
> the struct pointer will get a compiler error.

So the problem here is that we don't really want an opaque pointer in a classic 
sense, but an opaque field.

struct wake_q is:

  struct wake_q_node {
          struct wake_q_node *next;
  };

i.e. it's really just a single linked list node, a single pointer. This line:

> +       struct wake_q_node *node = (void *)&task->wake_q;

gets the pointer to the list node.

Couldn't think of a nicer way to do this - so let's not do this at all: we can 
just declare struct wake_q_node in sched.h and be done with it. We saved thousands 
of lines of code from it already, it's not worth doing it at the cost of strong 
type safety.

I.e. something like the patch attached below on top of WIP.sched/core?

Untested.

Thanks,

	Ingo


==============================>
From fe7014cb9736f84f01f36003d72ed69d795ea82b Mon Sep 17 00:00:00 2001
From: Ingo Molnar <mingo@kernel.org>
Date: Wed, 8 Feb 2017 22:32:31 +0100
Subject: [PATCH] sched/wake_q: Restore task_struct::wake_q type safety

Linus correctly observed that task_struct::wake_q is an opaque pointer
in a rather ugly way, through which we lose not just readability but
also type safety, for only marginal savings in sched.h.

Just restore the 'struct wake_q_node' type in sched.h and include
sched.h in sched/wake_q.h.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 include/linux/sched.h        | 6 +++++-
 include/linux/sched/wake_q.h | 6 +-----
 ipc/msg.c                    | 1 -
 kernel/fork.c                | 2 +-
 kernel/sched/core.c          | 6 +++---
 5 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 2cc4d7902418..d67eee84fd43 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -476,6 +476,10 @@ enum perf_event_task_context {
 	perf_nr_task_contexts,
 };
 
+struct wake_q_node {
+	struct wake_q_node *next;
+};
+
 struct task_struct {
 #ifdef CONFIG_THREAD_INFO_IN_TASK
 	/*
@@ -765,7 +769,7 @@ struct task_struct {
 	/* Protection of the PI data structures: */
 	raw_spinlock_t			pi_lock;
 
-	void				*wake_q;
+	struct wake_q_node		wake_q;
 
 #ifdef CONFIG_RT_MUTEXES
 	/* PI waiters blocked on a rt_mutex held by this task: */
diff --git a/include/linux/sched/wake_q.h b/include/linux/sched/wake_q.h
index e6774a0385fb..d03d8a9047dc 100644
--- a/include/linux/sched/wake_q.h
+++ b/include/linux/sched/wake_q.h
@@ -28,11 +28,7 @@
  * wakeup condition has in fact occurred.
  */
 
-struct task_struct;
-
-struct wake_q_node {
-	struct wake_q_node *next;
-};
+#include <linux/sched.h>
 
 struct wake_q_head {
 	struct wake_q_node *first;
diff --git a/ipc/msg.c b/ipc/msg.c
index ecc387e573f6..104926dc72be 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -30,7 +30,6 @@
 #include <linux/proc_fs.h>
 #include <linux/list.h>
 #include <linux/security.h>
-#include <linux/sched.h>
 #include <linux/sched/wake_q.h>
 #include <linux/syscalls.h>
 #include <linux/audit.h>
diff --git a/kernel/fork.c b/kernel/fork.c
index 4a033bb7d660..68b1706c75d0 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -548,7 +548,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
 #endif
 	tsk->splice_pipe = NULL;
 	tsk->task_frag.page = NULL;
-	tsk->wake_q = NULL;
+	tsk->wake_q.next = NULL;
 
 	account_kernel_stack(tsk, 1);
 
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 0abcf7307428..a4fdb6b03577 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -431,7 +431,7 @@ static bool set_nr_if_polling(struct task_struct *p)
 
 void wake_q_add(struct wake_q_head *head, struct task_struct *task)
 {
-	struct wake_q_node *node = (void *)&task->wake_q;
+	struct wake_q_node *node = &task->wake_q;
 
 	/*
 	 * Atomically grab the task, if ->wake_q is !nil already it means
@@ -460,11 +460,11 @@ void wake_up_q(struct wake_q_head *head)
 	while (node != WAKE_Q_TAIL) {
 		struct task_struct *task;
 
-		task = container_of((void *)node, struct task_struct, wake_q);
+		task = container_of(node, struct task_struct, wake_q);
 		BUG_ON(!task);
 		/* Task can safely be re-inserted now: */
 		node = node->next;
-		task->wake_q = NULL;
+		task->wake_q.next = NULL;
 
 		/*
 		 * wake_up_process() implies a wmb() to pair with the queueing

[toc] | [prev] | [next] | [standalone]


#1576843 — [PATCH 08/10] sched/headers, cgroups: Remove the threadgroup_change_*() wrappery

FromIngo Molnar <mingo@kernel.org>
Date2017-02-08 19:50 +0100
Subject[PATCH 08/10] sched/headers, cgroups: Remove the threadgroup_change_*() wrappery
Message-ID<t8Ftx-3Sf-53@gated-at.bofh.it>
In reply to#1576817
threadgroup_change_begin()/end() is a pointless wrapper around
cgroup_threadgroup_change_begin()/end(), minus a might_sleep()
in the !CONFIG_CGROUPS=y case.

Remove the wrappery, move the might_sleep() (the down_read()
already has a might_sleep() check).

This debloats <linux/sched.h> a bit and simplifies this API.

Update all call sites.

No change in functionality.

Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 fs/exec.c                   |  6 +++---
 include/linux/cgroup-defs.h | 13 ++++++++-----
 include/linux/sched.h       | 28 ----------------------------
 kernel/cgroup_pids.c        |  2 +-
 kernel/fork.c               |  6 +++---
 kernel/signal.c             |  6 +++---
 6 files changed, 18 insertions(+), 43 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index e57946610733..61768d1dacc4 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1088,7 +1088,7 @@ static int de_thread(struct task_struct *tsk)
 		struct task_struct *leader = tsk->group_leader;
 
 		for (;;) {
-			threadgroup_change_begin(tsk);
+			cgroup_threadgroup_change_begin(tsk);
 			write_lock_irq(&tasklist_lock);
 			/*
 			 * Do this under tasklist_lock to ensure that
@@ -1099,7 +1099,7 @@ static int de_thread(struct task_struct *tsk)
 				break;
 			__set_current_state(TASK_KILLABLE);
 			write_unlock_irq(&tasklist_lock);
-			threadgroup_change_end(tsk);
+			cgroup_threadgroup_change_end(tsk);
 			schedule();
 			if (unlikely(__fatal_signal_pending(tsk)))
 				goto killed;
@@ -1157,7 +1157,7 @@ static int de_thread(struct task_struct *tsk)
 		if (unlikely(leader->ptrace))
 			__wake_up_parent(leader, leader->parent);
 		write_unlock_irq(&tasklist_lock);
-		threadgroup_change_end(tsk);
+		cgroup_threadgroup_change_end(tsk);
 
 		release_task(leader);
 	}
diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h
index 861b4677fc5b..c5eac7631377 100644
--- a/include/linux/cgroup-defs.h
+++ b/include/linux/cgroup-defs.h
@@ -528,8 +528,8 @@ extern struct percpu_rw_semaphore cgroup_threadgroup_rwsem;
  * cgroup_threadgroup_change_begin - threadgroup exclusion for cgroups
  * @tsk: target task
  *
- * Called from threadgroup_change_begin() and allows cgroup operations to
- * synchronize against threadgroup changes using a percpu_rw_semaphore.
+ * Allows cgroup operations to synchronize against threadgroup changes
+ * using a percpu_rw_semaphore.
  */
 static inline void cgroup_threadgroup_change_begin(struct task_struct *tsk)
 {
@@ -540,8 +540,7 @@ static inline void cgroup_threadgroup_change_begin(struct task_struct *tsk)
  * cgroup_threadgroup_change_end - threadgroup exclusion for cgroups
  * @tsk: target task
  *
- * Called from threadgroup_change_end().  Counterpart of
- * cgroup_threadcgroup_change_begin().
+ * Counterpart of cgroup_threadcgroup_change_begin().
  */
 static inline void cgroup_threadgroup_change_end(struct task_struct *tsk)
 {
@@ -552,7 +551,11 @@ static inline void cgroup_threadgroup_change_end(struct task_struct *tsk)
 
 #define CGROUP_SUBSYS_COUNT 0
 
-static inline void cgroup_threadgroup_change_begin(struct task_struct *tsk) {}
+static inline void cgroup_threadgroup_change_begin(struct task_struct *tsk)
+{
+	might_sleep();
+}
+
 static inline void cgroup_threadgroup_change_end(struct task_struct *tsk) {}
 
 #endif	/* CONFIG_CGROUPS */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 4e2e738e2c61..76c903685e78 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -3120,34 +3120,6 @@ static inline void unlock_task_sighand(struct task_struct *tsk,
 	spin_unlock_irqrestore(&tsk->sighand->siglock, *flags);
 }
 
-/**
- * threadgroup_change_begin - mark the beginning of changes to a threadgroup
- * @tsk: task causing the changes
- *
- * All operations which modify a threadgroup - a new thread joining the
- * group, death of a member thread (the assertion of PF_EXITING) and
- * exec(2) dethreading the process and replacing the leader - are wrapped
- * by threadgroup_change_{begin|end}().  This is to provide a place which
- * subsystems needing threadgroup stability can hook into for
- * synchronization.
- */
-static inline void threadgroup_change_begin(struct task_struct *tsk)
-{
-	might_sleep();
-	cgroup_threadgroup_change_begin(tsk);
-}
-
-/**
- * threadgroup_change_end - mark the end of changes to a threadgroup
- * @tsk: task causing the changes
- *
- * See threadgroup_change_begin().
- */
-static inline void threadgroup_change_end(struct task_struct *tsk)
-{
-	cgroup_threadgroup_change_end(tsk);
-}
-
 #ifdef CONFIG_THREAD_INFO_IN_TASK
 
 static inline struct thread_info *task_thread_info(struct task_struct *task)
diff --git a/kernel/cgroup_pids.c b/kernel/cgroup_pids.c
index 2bd673783f1a..e756dae49300 100644
--- a/kernel/cgroup_pids.c
+++ b/kernel/cgroup_pids.c
@@ -214,7 +214,7 @@ static void pids_cancel_attach(struct cgroup_taskset *tset)
 
 /*
  * task_css_check(true) in pids_can_fork() and pids_cancel_fork() relies
- * on threadgroup_change_begin() held by the copy_process().
+ * on cgroup_threadgroup_change_begin() held by the copy_process().
  */
 static int pids_can_fork(struct task_struct *task)
 {
diff --git a/kernel/fork.c b/kernel/fork.c
index 9aa2ca28a76c..8874f75e5a79 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1745,7 +1745,7 @@ static __latent_entropy struct task_struct *copy_process(
 	INIT_LIST_HEAD(&p->thread_group);
 	p->task_works = NULL;
 
-	threadgroup_change_begin(current);
+	cgroup_threadgroup_change_begin(current);
 	/*
 	 * Ensure that the cgroup subsystem policies allow the new process to be
 	 * forked. It should be noted the the new process's css_set can be changed
@@ -1835,7 +1835,7 @@ static __latent_entropy struct task_struct *copy_process(
 
 	proc_fork_connector(p);
 	cgroup_post_fork(p);
-	threadgroup_change_end(current);
+	cgroup_threadgroup_change_end(current);
 	perf_event_fork(p);
 
 	trace_task_newtask(p, clone_flags);
@@ -1846,7 +1846,7 @@ static __latent_entropy struct task_struct *copy_process(
 bad_fork_cancel_cgroup:
 	cgroup_cancel_fork(p);
 bad_fork_free_pid:
-	threadgroup_change_end(current);
+	cgroup_threadgroup_change_end(current);
 	if (pid != &init_struct_pid)
 		free_pid(pid);
 bad_fork_cleanup_thread:
diff --git a/kernel/signal.c b/kernel/signal.c
index 13f9def8b24a..e5aafa1e4835 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2395,11 +2395,11 @@ void exit_signals(struct task_struct *tsk)
 	 * @tsk is about to have PF_EXITING set - lock out users which
 	 * expect stable threadgroup.
 	 */
-	threadgroup_change_begin(tsk);
+	cgroup_threadgroup_change_begin(tsk);
 
 	if (thread_group_empty(tsk) || signal_group_exit(tsk->signal)) {
 		tsk->flags |= PF_EXITING;
-		threadgroup_change_end(tsk);
+		cgroup_threadgroup_change_end(tsk);
 		return;
 	}
 
@@ -2410,7 +2410,7 @@ void exit_signals(struct task_struct *tsk)
 	 */
 	tsk->flags |= PF_EXITING;
 
-	threadgroup_change_end(tsk);
+	cgroup_threadgroup_change_end(tsk);
 
 	if (!signal_pending(tsk))
 		goto out;
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1576914 — [PATCH 10/10] kasan, sched/headers: Uninline kasan_enable/disable_current()

FromIngo Molnar <mingo@kernel.org>
Date2017-02-08 20:10 +0100
Subject[PATCH 10/10] kasan, sched/headers: Uninline kasan_enable/disable_current()
Message-ID<t8FMU-4eP-71@gated-at.bofh.it>
In reply to#1576817
<linux/kasan.h> is a low level header that is included early
in affected kernel headers. But it includes <linux/sched.h>
which complicates the cleanup of sched.h dependencies.

But kasan.h has almost no need for sched.h: its only use of
scheduler functionality is in two inline functions which are
not used very frequently - so uninline kasan_enable_current()
and kasan_disable_current().

Also add a <linux/sched.h> dependency to a .c file that depended
on kasan.h including it.

This paves the way to remove the <linux/sched.h> include from kasan.h.

Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 include/linux/kasan.h | 10 ++--------
 lib/sbitmap.c         |  1 +
 mm/kasan/kasan.c      | 10 ++++++++++
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index 820c0ad54a01..96ef4c33148d 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -30,16 +30,10 @@ static inline void *kasan_mem_to_shadow(const void *addr)
 }
 
 /* Enable reporting bugs after kasan_disable_current() */
-static inline void kasan_enable_current(void)
-{
-	current->kasan_depth++;
-}
+extern void kasan_enable_current(void);
 
 /* Disable reporting bugs for current task */
-static inline void kasan_disable_current(void)
-{
-	current->kasan_depth--;
-}
+extern void kasan_disable_current(void);
 
 void kasan_unpoison_shadow(const void *address, size_t size);
 
diff --git a/lib/sbitmap.c b/lib/sbitmap.c
index 2cecf05c82fd..8641ca20a4f0 100644
--- a/lib/sbitmap.c
+++ b/lib/sbitmap.c
@@ -15,6 +15,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
+#include <linux/sched.h>
 #include <linux/random.h>
 #include <linux/sbitmap.h>
 
diff --git a/mm/kasan/kasan.c b/mm/kasan/kasan.c
index b2a0cff2bb35..37d39f7f6260 100644
--- a/mm/kasan/kasan.c
+++ b/mm/kasan/kasan.c
@@ -39,6 +39,16 @@
 #include "kasan.h"
 #include "../slab.h"
 
+void kasan_enable_current(void)
+{
+	current->kasan_depth++;
+}
+
+void kasan_disable_current(void)
+{
+	current->kasan_depth--;
+}
+
 /*
  * Poisons the shadow memory for 'size' bytes starting from 'addr'.
  * Memory addresses should be aligned to KASAN_SHADOW_SCALE_SIZE.
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1576993 — [PATCH 09/10] mm/vmacache, sched/headers: Introduce 'struct vmacache' and move it from <linux/sched.h> to <linux/mm_types>

FromIngo Molnar <mingo@kernel.org>
Date2017-02-08 20:50 +0100
Subject[PATCH 09/10] mm/vmacache, sched/headers: Introduce 'struct vmacache' and move it from <linux/sched.h> to <linux/mm_types>
Message-ID<t8GpB-4sD-37@gated-at.bofh.it>
In reply to#1576817
The <linux/sched.h> header includes various vmacache related defines,
which are arguably misplaced.

Move them to mm_types.h and minimize the sched.h impact by putting
all task vmacache state into a new 'struct vmacache' structure.

No change in functionality.

Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 include/linux/mm_types.h  | 12 ++++++++++++
 include/linux/sched.h     | 11 ++++-------
 include/linux/vmacache.h  |  2 +-
 kernel/debug/debug_core.c |  4 ++--
 mm/nommu.c                |  2 +-
 mm/vmacache.c             | 10 +++++-----
 6 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 808751d7b737..3fd0713f2f3f 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -360,6 +360,18 @@ struct vm_area_struct {
 	struct vm_userfaultfd_ctx vm_userfaultfd_ctx;
 };
 
+/*
+ * The per task VMA cache array:
+ */
+#define VMACACHE_BITS 2
+#define VMACACHE_SIZE (1U << VMACACHE_BITS)
+#define VMACACHE_MASK (VMACACHE_SIZE - 1)
+
+struct vmacache {
+	u32 seqnum;
+	struct vm_area_struct *vmas[VMACACHE_SIZE];
+};
+
 struct core_thread {
 	struct task_struct *task;
 	struct core_thread *next;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 76c903685e78..719f0253bdbf 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -134,10 +134,6 @@ struct blk_plug;
 struct filename;
 struct nameidata;
 
-#define VMACACHE_BITS 2
-#define VMACACHE_SIZE (1U << VMACACHE_BITS)
-#define VMACACHE_MASK (VMACACHE_SIZE - 1)
-
 /*
  * These are the constant used to fake the fixed-point load-average
  * counting. Some notes:
@@ -1554,9 +1550,10 @@ struct task_struct {
 #endif
 
 	struct mm_struct *mm, *active_mm;
-	/* per-thread vma caching */
-	u32 vmacache_seqnum;
-	struct vm_area_struct *vmacache[VMACACHE_SIZE];
+
+	/* Per-thread vma caching: */
+	struct vmacache vmacache;
+
 #if defined(SPLIT_RSS_COUNTING)
 	struct task_rss_stat	rss_stat;
 #endif
diff --git a/include/linux/vmacache.h b/include/linux/vmacache.h
index c3fa0fd43949..1081db987391 100644
--- a/include/linux/vmacache.h
+++ b/include/linux/vmacache.h
@@ -12,7 +12,7 @@
 
 static inline void vmacache_flush(struct task_struct *tsk)
 {
-	memset(tsk->vmacache, 0, sizeof(tsk->vmacache));
+	memset(tsk->vmacache.vmas, 0, sizeof(tsk->vmacache.vmas));
 }
 
 extern void vmacache_flush_all(struct mm_struct *mm);
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
index 79517e5549f1..a603ef28f70c 100644
--- a/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -232,9 +232,9 @@ static void kgdb_flush_swbreak_addr(unsigned long addr)
 		int i;
 
 		for (i = 0; i < VMACACHE_SIZE; i++) {
-			if (!current->vmacache[i])
+			if (!current->vmacache.vmas[i])
 				continue;
-			flush_cache_range(current->vmacache[i],
+			flush_cache_range(current->vmacache.vmas[i],
 					  addr, addr + BREAK_INSTR_SIZE);
 		}
 	}
diff --git a/mm/nommu.c b/mm/nommu.c
index 24f9f5f39145..842f2463ed1b 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -757,7 +757,7 @@ static void delete_vma_from_mm(struct vm_area_struct *vma)
 	mm->map_count--;
 	for (i = 0; i < VMACACHE_SIZE; i++) {
 		/* if the vma is cached, invalidate the entire cache */
-		if (curr->vmacache[i] == vma) {
+		if (curr->vmacache.vmas[i] == vma) {
 			vmacache_invalidate(mm);
 			break;
 		}
diff --git a/mm/vmacache.c b/mm/vmacache.c
index 035fdeb35b43..7c233f8e20ee 100644
--- a/mm/vmacache.c
+++ b/mm/vmacache.c
@@ -60,7 +60,7 @@ static inline bool vmacache_valid_mm(struct mm_struct *mm)
 void vmacache_update(unsigned long addr, struct vm_area_struct *newvma)
 {
 	if (vmacache_valid_mm(newvma->vm_mm))
-		current->vmacache[VMACACHE_HASH(addr)] = newvma;
+		current->vmacache.vmas[VMACACHE_HASH(addr)] = newvma;
 }
 
 static bool vmacache_valid(struct mm_struct *mm)
@@ -71,12 +71,12 @@ static bool vmacache_valid(struct mm_struct *mm)
 		return false;
 
 	curr = current;
-	if (mm->vmacache_seqnum != curr->vmacache_seqnum) {
+	if (mm->vmacache_seqnum != curr->vmacache.seqnum) {
 		/*
 		 * First attempt will always be invalid, initialize
 		 * the new cache for this task here.
 		 */
-		curr->vmacache_seqnum = mm->vmacache_seqnum;
+		curr->vmacache.seqnum = mm->vmacache_seqnum;
 		vmacache_flush(curr);
 		return false;
 	}
@@ -93,7 +93,7 @@ struct vm_area_struct *vmacache_find(struct mm_struct *mm, unsigned long addr)
 		return NULL;
 
 	for (i = 0; i < VMACACHE_SIZE; i++) {
-		struct vm_area_struct *vma = current->vmacache[i];
+		struct vm_area_struct *vma = current->vmacache.vmas[i];
 
 		if (!vma)
 			continue;
@@ -121,7 +121,7 @@ struct vm_area_struct *vmacache_find_exact(struct mm_struct *mm,
 		return NULL;
 
 	for (i = 0; i < VMACACHE_SIZE; i++) {
-		struct vm_area_struct *vma = current->vmacache[i];
+		struct vm_area_struct *vma = current->vmacache.vmas[i];
 
 		if (vma && vma->vm_start == start && vma->vm_end == end) {
 			count_vm_vmacache_event(VMACACHE_FIND_HITS);
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1576997 — [PATCH 07/10] rcu: Separate the RCU synchronization types and APIs into <linux/rcupdate_wait.h>

FromIngo Molnar <mingo@kernel.org>
Date2017-02-08 20:50 +0100
Subject[PATCH 07/10] rcu: Separate the RCU synchronization types and APIs into <linux/rcupdate_wait.h>
Message-ID<t8GpB-4sD-43@gated-at.bofh.it>
In reply to#1576817
So rcupdate.h is a pretty complex header, in particular it includes
<linux/completion.h> which includes <linux/wait.h> - creating a
dependency that includes <linux/wait.h> in <linux/sched.h>,
which prevents the isolation of <linux/sched.h> from the derived
<linux/wait.h> header.

Solve part of the problem by decoupling rcupdate.h from completions:
this can be done by separating out the rcu_synchronize types and APIs,
and updating their usage sites.

Since this is a mostly RCU-internal types this will not just simplify
<linux/sched.h>'s dependencies, but will make all the hundreds of
.c files that include rcupdate.h but not completions or wait.h build
faster.

( For rcutiny this means that two dependent APIs have to be uninlined,
  but that shouldn't be much of a problem as they are rare variants. )

Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 fs/autofs4/autofs_i.h         |  1 +
 include/linux/dcache.h        |  1 +
 include/linux/rcupdate.h      | 40 ----------------------------------------
 include/linux/rcupdate_wait.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/rcutiny.h       | 11 ++---------
 kernel/rcu/srcu.c             |  2 +-
 kernel/rcu/tiny.c             | 14 +++++++++++++-
 kernel/rcu/tree.c             |  2 +-
 kernel/rcu/update.c           |  1 +
 kernel/sched/core.c           |  1 +
 10 files changed, 71 insertions(+), 52 deletions(-)

diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index c885daae68c8..beef981aa54f 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -14,6 +14,7 @@
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
 #include <linux/list.h>
+#include <linux/completion.h>
 
 /* This is the range of ioctl() numbers we claim as ours */
 #define AUTOFS_IOC_FIRST     AUTOFS_IOC_READY
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index c965e4469499..16948defb568 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -11,6 +11,7 @@
 #include <linux/rcupdate.h>
 #include <linux/lockref.h>
 #include <linux/stringhash.h>
+#include <linux/wait.h>
 
 struct path;
 struct vfsmount;
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 01f71e1d2e94..1f476b63c596 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -40,7 +40,6 @@
 #include <linux/cpumask.h>
 #include <linux/seqlock.h>
 #include <linux/lockdep.h>
-#include <linux/completion.h>
 #include <linux/debugobjects.h>
 #include <linux/bug.h>
 #include <linux/compiler.h>
@@ -226,45 +225,6 @@ void call_rcu_sched(struct rcu_head *head,
 
 void synchronize_sched(void);
 
-/*
- * Structure allowing asynchronous waiting on RCU.
- */
-struct rcu_synchronize {
-	struct rcu_head head;
-	struct completion completion;
-};
-void wakeme_after_rcu(struct rcu_head *head);
-
-void __wait_rcu_gp(bool checktiny, int n, call_rcu_func_t *crcu_array,
-		   struct rcu_synchronize *rs_array);
-
-#define _wait_rcu_gp(checktiny, ...) \
-do {									\
-	call_rcu_func_t __crcu_array[] = { __VA_ARGS__ };		\
-	struct rcu_synchronize __rs_array[ARRAY_SIZE(__crcu_array)];	\
-	__wait_rcu_gp(checktiny, ARRAY_SIZE(__crcu_array),		\
-			__crcu_array, __rs_array);			\
-} while (0)
-
-#define wait_rcu_gp(...) _wait_rcu_gp(false, __VA_ARGS__)
-
-/**
- * synchronize_rcu_mult - Wait concurrently for multiple grace periods
- * @...: List of call_rcu() functions for the flavors to wait on.
- *
- * This macro waits concurrently for multiple flavors of RCU grace periods.
- * For example, synchronize_rcu_mult(call_rcu, call_rcu_bh) would wait
- * on concurrent RCU and RCU-bh grace periods.  Waiting on a give SRCU
- * domain requires you to write a wrapper function for that SRCU domain's
- * call_srcu() function, supplying the corresponding srcu_struct.
- *
- * If Tiny RCU, tell _wait_rcu_gp() not to bother waiting for RCU
- * or RCU-bh, given that anywhere synchronize_rcu_mult() can be called
- * is automatically a grace period.
- */
-#define synchronize_rcu_mult(...) \
-	_wait_rcu_gp(IS_ENABLED(CONFIG_TINY_RCU), __VA_ARGS__)
-
 /**
  * call_rcu_tasks() - Queue an RCU for invocation task-based grace period
  * @head: structure to be used for queueing the RCU updates.
diff --git a/include/linux/rcupdate_wait.h b/include/linux/rcupdate_wait.h
new file mode 100644
index 000000000000..e774b4f5f220
--- /dev/null
+++ b/include/linux/rcupdate_wait.h
@@ -0,0 +1,50 @@
+#ifndef _LINUX_SCHED_RCUPDATE_WAIT_H
+#define _LINUX_SCHED_RCUPDATE_WAIT_H
+
+/*
+ * RCU synchronization types and methods:
+ */
+
+#include <linux/rcupdate.h>
+#include <linux/completion.h>
+
+/*
+ * Structure allowing asynchronous waiting on RCU.
+ */
+struct rcu_synchronize {
+	struct rcu_head head;
+	struct completion completion;
+};
+void wakeme_after_rcu(struct rcu_head *head);
+
+void __wait_rcu_gp(bool checktiny, int n, call_rcu_func_t *crcu_array,
+		   struct rcu_synchronize *rs_array);
+
+#define _wait_rcu_gp(checktiny, ...) \
+do {									\
+	call_rcu_func_t __crcu_array[] = { __VA_ARGS__ };		\
+	struct rcu_synchronize __rs_array[ARRAY_SIZE(__crcu_array)];	\
+	__wait_rcu_gp(checktiny, ARRAY_SIZE(__crcu_array),		\
+			__crcu_array, __rs_array);			\
+} while (0)
+
+#define wait_rcu_gp(...) _wait_rcu_gp(false, __VA_ARGS__)
+
+/**
+ * synchronize_rcu_mult - Wait concurrently for multiple grace periods
+ * @...: List of call_rcu() functions for the flavors to wait on.
+ *
+ * This macro waits concurrently for multiple flavors of RCU grace periods.
+ * For example, synchronize_rcu_mult(call_rcu, call_rcu_bh) would wait
+ * on concurrent RCU and RCU-bh grace periods.  Waiting on a give SRCU
+ * domain requires you to write a wrapper function for that SRCU domain's
+ * call_srcu() function, supplying the corresponding srcu_struct.
+ *
+ * If Tiny RCU, tell _wait_rcu_gp() not to bother waiting for RCU
+ * or RCU-bh, given that anywhere synchronize_rcu_mult() can be called
+ * is automatically a grace period.
+ */
+#define synchronize_rcu_mult(...) \
+	_wait_rcu_gp(IS_ENABLED(CONFIG_TINY_RCU), __VA_ARGS__)
+
+#endif /* _LINUX_SCHED_RCUPDATE_WAIT_H */
diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h
index ac81e4063b40..861ab86ae302 100644
--- a/include/linux/rcutiny.h
+++ b/include/linux/rcutiny.h
@@ -47,15 +47,8 @@ static inline void cond_synchronize_sched(unsigned long oldstate)
 	might_sleep();
 }
 
-static inline void rcu_barrier_bh(void)
-{
-	wait_rcu_gp(call_rcu_bh);
-}
-
-static inline void rcu_barrier_sched(void)
-{
-	wait_rcu_gp(call_rcu_sched);
-}
+extern void rcu_barrier_bh(void);
+extern void rcu_barrier_sched(void);
 
 static inline void synchronize_rcu_expedited(void)
 {
diff --git a/kernel/rcu/srcu.c b/kernel/rcu/srcu.c
index 9b9cdd549caa..c05855490b54 100644
--- a/kernel/rcu/srcu.c
+++ b/kernel/rcu/srcu.c
@@ -30,7 +30,7 @@
 #include <linux/mutex.h>
 #include <linux/percpu.h>
 #include <linux/preempt.h>
-#include <linux/rcupdate.h>
+#include <linux/rcupdate_wait.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/delay.h>
diff --git a/kernel/rcu/tiny.c b/kernel/rcu/tiny.c
index b23a4d076f3d..55770f10342e 100644
--- a/kernel/rcu/tiny.c
+++ b/kernel/rcu/tiny.c
@@ -25,7 +25,7 @@
 #include <linux/completion.h>
 #include <linux/interrupt.h>
 #include <linux/notifier.h>
-#include <linux/rcupdate.h>
+#include <linux/rcupdate_wait.h>
 #include <linux/kernel.h>
 #include <linux/export.h>
 #include <linux/mutex.h>
@@ -49,6 +49,18 @@ static void __call_rcu(struct rcu_head *head,
 
 #include "tiny_plugin.h"
 
+void rcu_barrier_bh(void)
+{
+	wait_rcu_gp(call_rcu_bh);
+}
+EXPORT_SYMBOL(rcu_barrier_bh);
+
+void rcu_barrier_sched(void)
+{
+	wait_rcu_gp(call_rcu_sched);
+}
+EXPORT_SYMBOL(rcu_barrier_sched);
+
 #if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE)
 
 /*
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index cb4e2056ccf3..2d87cb3ad7c6 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -32,7 +32,7 @@
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/smp.h>
-#include <linux/rcupdate.h>
+#include <linux/rcupdate_wait.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/nmi.h>
diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c
index 4f6db7e6a117..2730e5c9ad2e 100644
--- a/kernel/rcu/update.c
+++ b/kernel/rcu/update.c
@@ -49,6 +49,7 @@
 #include <linux/moduleparam.h>
 #include <linux/kthread.h>
 #include <linux/tick.h>
+#include <linux/rcupdate_wait.h>
 
 #define CREATE_TRACE_POINTS
 
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 258af6d00682..f3ce7cf60002 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -10,6 +10,7 @@
 #include <linux/delayacct.h>
 #include <linux/init_task.h>
 #include <linux/context_tracking.h>
+#include <linux/rcupdate_wait.h>
 
 #include <linux/blkdev.h>
 #include <linux/kprobes.h>
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1579088 — Re: [PATCH 07/10] rcu: Separate the RCU synchronization types and APIs into <linux/rcupdate_wait.h>

FromPaul McKenney <paulmckrcu@gmail.com>
Date2017-02-11 20:20 +0100
SubjectRe: [PATCH 07/10] rcu: Separate the RCU synchronization types and APIs into <linux/rcupdate_wait.h>
Message-ID<t9Lnc-4AA-7@gated-at.bofh.it>
In reply to#1576997
On Wed, Feb 8, 2017 at 10:34 AM, Ingo Molnar <mingo@kernel.org> wrote:
> So rcupdate.h is a pretty complex header, in particular it includes
> <linux/completion.h> which includes <linux/wait.h> - creating a
> dependency that includes <linux/wait.h> in <linux/sched.h>,
> which prevents the isolation of <linux/sched.h> from the derived
> <linux/wait.h> header.
>
> Solve part of the problem by decoupling rcupdate.h from completions:
> this can be done by separating out the rcu_synchronize types and APIs,
> and updating their usage sites.
>
> Since this is a mostly RCU-internal types this will not just simplify
> <linux/sched.h>'s dependencies, but will make all the hundreds of
> .c files that include rcupdate.h but not completions or wait.h build
> faster.

Indeed, rcupdate.h is overdue for a more sweeping overhaul.

> ( For rcutiny this means that two dependent APIs have to be uninlined,
>   but that shouldn't be much of a problem as they are rare variants. )

Do people still care about Tiny kernel?  If so, I can queue a patch
that leaves rcu_barrier_bh() and rcu_barrier_sched() inline, but
creates an rcu_barrier_generic() or some such, so that there is
space taken up by only one EXPORT_SYMBOL() instead of two.
(0day Test Robot yells at me every time I add one...)

Other than that, I don't see any problems with this.  I will do some
testing.

                                                           Thanx, Paul

> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> Cc: Mike Galbraith <efault@gmx.de>
> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Ingo Molnar <mingo@kernel.org>
> ---
>  fs/autofs4/autofs_i.h         |  1 +
>  include/linux/dcache.h        |  1 +
>  include/linux/rcupdate.h      | 40 ----------------------------------------
>  include/linux/rcupdate_wait.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/rcutiny.h       | 11 ++---------
>  kernel/rcu/srcu.c             |  2 +-
>  kernel/rcu/tiny.c             | 14 +++++++++++++-
>  kernel/rcu/tree.c             |  2 +-
>  kernel/rcu/update.c           |  1 +
>  kernel/sched/core.c           |  1 +
>  10 files changed, 71 insertions(+), 52 deletions(-)
>
> diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
> index c885daae68c8..beef981aa54f 100644
> --- a/fs/autofs4/autofs_i.h
> +++ b/fs/autofs4/autofs_i.h
> @@ -14,6 +14,7 @@
>  #include <linux/mutex.h>
>  #include <linux/spinlock.h>
>  #include <linux/list.h>
> +#include <linux/completion.h>
>
>  /* This is the range of ioctl() numbers we claim as ours */
>  #define AUTOFS_IOC_FIRST     AUTOFS_IOC_READY
> diff --git a/include/linux/dcache.h b/include/linux/dcache.h
> index c965e4469499..16948defb568 100644
> --- a/include/linux/dcache.h
> +++ b/include/linux/dcache.h
> @@ -11,6 +11,7 @@
>  #include <linux/rcupdate.h>
>  #include <linux/lockref.h>
>  #include <linux/stringhash.h>
> +#include <linux/wait.h>
>
>  struct path;
>  struct vfsmount;
> diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
> index 01f71e1d2e94..1f476b63c596 100644
> --- a/include/linux/rcupdate.h
> +++ b/include/linux/rcupdate.h
> @@ -40,7 +40,6 @@
>  #include <linux/cpumask.h>
>  #include <linux/seqlock.h>
>  #include <linux/lockdep.h>
> -#include <linux/completion.h>
>  #include <linux/debugobjects.h>
>  #include <linux/bug.h>
>  #include <linux/compiler.h>
> @@ -226,45 +225,6 @@ void call_rcu_sched(struct rcu_head *head,
>
>  void synchronize_sched(void);
>
> -/*
> - * Structure allowing asynchronous waiting on RCU.
> - */
> -struct rcu_synchronize {
> -       struct rcu_head head;
> -       struct completion completion;
> -};

> -void wakeme_after_rcu(struct rcu_head *head);> -
> -void __wait_rcu_gp(bool checktiny, int n, call_rcu_func_t *crcu_array,
> -                  struct rcu_synchronize *rs_array);
> -
> -#define _wait_rcu_gp(checktiny, ...) \
> -do {                                                                   \
> -       call_rcu_func_t __crcu_array[] = { __VA_ARGS__ };               \
> -       struct rcu_synchronize __rs_array[ARRAY_SIZE(__crcu_array)];    \
> -       __wait_rcu_gp(checktiny, ARRAY_SIZE(__crcu_array),              \
> -                       __crcu_array, __rs_array);                      \
> -} while (0)
> -
> -#define wait_rcu_gp(...) _wait_rcu_gp(false, __VA_ARGS__)
> -
> -/**
> - * synchronize_rcu_mult - Wait concurrently for multiple grace periods
> - * @...: List of call_rcu() functions for the flavors to wait on.
> - *
> - * This macro waits concurrently for multiple flavors of RCU grace periods.
> - * For example, synchronize_rcu_mult(call_rcu, call_rcu_bh) would wait
> - * on concurrent RCU and RCU-bh grace periods.  Waiting on a give SRCU
> - * domain requires you to write a wrapper function for that SRCU domain's
> - * call_srcu() function, supplying the corresponding srcu_struct.
> - *
> - * If Tiny RCU, tell _wait_rcu_gp() not to bother waiting for RCU
> - * or RCU-bh, given that anywhere synchronize_rcu_mult() can be called
> - * is automatically a grace period.
> - */
> -#define synchronize_rcu_mult(...) \
> -       _wait_rcu_gp(IS_ENABLED(CONFIG_TINY_RCU), __VA_ARGS__)
> -
>  /**
>   * call_rcu_tasks() - Queue an RCU for invocation task-based grace period
>   * @head: structure to be used for queueing the RCU updates.
> diff --git a/include/linux/rcupdate_wait.h b/include/linux/rcupdate_wait.h
> new file mode 100644
> index 000000000000..e774b4f5f220
> --- /dev/null
> +++ b/include/linux/rcupdate_wait.h
> @@ -0,0 +1,50 @@
> +#ifndef _LINUX_SCHED_RCUPDATE_WAIT_H
> +#define _LINUX_SCHED_RCUPDATE_WAIT_H
> +
> +/*
> + * RCU synchronization types and methods:
> + */
> +
> +#include <linux/rcupdate.h>
> +#include <linux/completion.h>
> +
> +/*
> + * Structure allowing asynchronous waiting on RCU.
> + */
> +struct rcu_synchronize {
> +       struct rcu_head head;
> +       struct completion completion;
> +};
> +void wakeme_after_rcu(struct rcu_head *head);
> +
> +void __wait_rcu_gp(bool checktiny, int n, call_rcu_func_t *crcu_array,
> +                  struct rcu_synchronize *rs_array);
> +
> +#define _wait_rcu_gp(checktiny, ...) \
> +do {                                                                   \
> +       call_rcu_func_t __crcu_array[] = { __VA_ARGS__ };               \
> +       struct rcu_synchronize __rs_array[ARRAY_SIZE(__crcu_array)];    \
> +       __wait_rcu_gp(checktiny, ARRAY_SIZE(__crcu_array),              \
> +                       __crcu_array, __rs_array);                      \
> +} while (0)
> +
> +#define wait_rcu_gp(...) _wait_rcu_gp(false, __VA_ARGS__)
> +
> +/**
> + * synchronize_rcu_mult - Wait concurrently for multiple grace periods
> + * @...: List of call_rcu() functions for the flavors to wait on.
> + *
> + * This macro waits concurrently for multiple flavors of RCU grace periods.
> + * For example, synchronize_rcu_mult(call_rcu, call_rcu_bh) would wait
> + * on concurrent RCU and RCU-bh grace periods.  Waiting on a give SRCU
> + * domain requires you to write a wrapper function for that SRCU domain's
> + * call_srcu() function, supplying the corresponding srcu_struct.
> + *
> + * If Tiny RCU, tell _wait_rcu_gp() not to bother waiting for RCU
> + * or RCU-bh, given that anywhere synchronize_rcu_mult() can be called
> + * is automatically a grace period.
> + */
> +#define synchronize_rcu_mult(...) \
> +       _wait_rcu_gp(IS_ENABLED(CONFIG_TINY_RCU), __VA_ARGS__)
> +
> +#endif /* _LINUX_SCHED_RCUPDATE_WAIT_H */
> diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h
> index ac81e4063b40..861ab86ae302 100644
> --- a/include/linux/rcutiny.h
> +++ b/include/linux/rcutiny.h
> @@ -47,15 +47,8 @@ static inline void cond_synchronize_sched(unsigned long oldstate)
>         might_sleep();
>  }
>
> -static inline void rcu_barrier_bh(void)
> -{
> -       wait_rcu_gp(call_rcu_bh);
> -}
> -
> -static inline void rcu_barrier_sched(void)
> -{
> -       wait_rcu_gp(call_rcu_sched);
> -}
> +extern void rcu_barrier_bh(void);
> +extern void rcu_barrier_sched(void);
>
>  static inline void synchronize_rcu_expedited(void)
>  {
> diff --git a/kernel/rcu/srcu.c b/kernel/rcu/srcu.c
> index 9b9cdd549caa..c05855490b54 100644
> --- a/kernel/rcu/srcu.c
> +++ b/kernel/rcu/srcu.c
> @@ -30,7 +30,7 @@
>  #include <linux/mutex.h>
>  #include <linux/percpu.h>
>  #include <linux/preempt.h>
> -#include <linux/rcupdate.h>
> +#include <linux/rcupdate_wait.h>
>  #include <linux/sched.h>
>  #include <linux/smp.h>
>  #include <linux/delay.h>
> diff --git a/kernel/rcu/tiny.c b/kernel/rcu/tiny.c
> index b23a4d076f3d..55770f10342e 100644
> --- a/kernel/rcu/tiny.c
> +++ b/kernel/rcu/tiny.c
> @@ -25,7 +25,7 @@
>  #include <linux/completion.h>
>  #include <linux/interrupt.h>
>  #include <linux/notifier.h>
> -#include <linux/rcupdate.h>
> +#include <linux/rcupdate_wait.h>
>  #include <linux/kernel.h>
>  #include <linux/export.h>
>  #include <linux/mutex.h>
> @@ -49,6 +49,18 @@ static void __call_rcu(struct rcu_head *head,
>
>  #include "tiny_plugin.h"
>
> +void rcu_barrier_bh(void)
> +{
> +       wait_rcu_gp(call_rcu_bh);
> +}
> +EXPORT_SYMBOL(rcu_barrier_bh);
> +
> +void rcu_barrier_sched(void)
> +{
> +       wait_rcu_gp(call_rcu_sched);
> +}
> +EXPORT_SYMBOL(rcu_barrier_sched);
> +
>  #if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE)
>
>  /*
> diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> index cb4e2056ccf3..2d87cb3ad7c6 100644
> --- a/kernel/rcu/tree.c
> +++ b/kernel/rcu/tree.c
> @@ -32,7 +32,7 @@
>  #include <linux/init.h>
>  #include <linux/spinlock.h>
>  #include <linux/smp.h>
> -#include <linux/rcupdate.h>
> +#include <linux/rcupdate_wait.h>
>  #include <linux/interrupt.h>
>  #include <linux/sched.h>
>  #include <linux/nmi.h>
> diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c
> index 4f6db7e6a117..2730e5c9ad2e 100644
> --- a/kernel/rcu/update.c
> +++ b/kernel/rcu/update.c
> @@ -49,6 +49,7 @@
>  #include <linux/moduleparam.h>
>  #include <linux/kthread.h>
>  #include <linux/tick.h>
> +#include <linux/rcupdate_wait.h>
>
>  #define CREATE_TRACE_POINTS
>
> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index 258af6d00682..f3ce7cf60002 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -10,6 +10,7 @@
>  #include <linux/delayacct.h>
>  #include <linux/init_task.h>
>  #include <linux/context_tracking.h>
> +#include <linux/rcupdate_wait.h>
>
>  #include <linux/blkdev.h>
>  #include <linux/kprobes.h>
> --
> 2.7.4
>

[toc] | [prev] | [next] | [standalone]


#1577026

FromLinus Torvalds <torvalds@linux-foundation.org>
Date2017-02-08 21:30 +0100
Message-ID<t8H2i-4VH-27@gated-at.bofh.it>
In reply to#1576817
On Wed, Feb 8, 2017 at 10:34 AM, Ingo Molnar <mingo@kernel.org> wrote:
>
>   phase #1: "Pre-splitup cleanups":               # 0721da143d99~1..582c7529a1bd,   10 patches
>
>   phase #2: "Prepare header dependencies":        # 9017f600c534~1..d1eb6f0b580d,   48 patches
>   phase #3: "Move definitions between headers":   # 3d01f4b6e32d~1..fd88c1773dd6,   53 patches
>   phase #4: "Remove header dependencies":         # 2d246f83c5d3~1..2205323e0ca1,   35 patches
>
>   phase #5: "Post-splitup cleanups":              # 55cf8bfb3af4~1..bcc6be9d66b2,    2 patches

So this seemed to be easier to go through, although I basically
skipped all the one-liners so who knows what conflict markers might
have been hiding there ;^)

I would personally have preferred phase 2/3 to be done in the reverse
order (by having the "move definitions" phase just add an include in
<sched.h> to still get them after the move), but it's not a huge issue
and I doubt it's worth re-doing the series over it.

I noted a couple of nits I found, but in general I think you can just
add my ack to this.

                Linus

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web