Merge tag 'for-linus-20191003' of git://git.kernel.org/pub/scm/linux/kernel/git/braun...
[linux-2.6-block.git] / kernel / sched / sched.h
index b3cb895d14a2088eef7a8853f00e7fc9b5823dd6..0db2c1b3361e03077d3971876f9dc06cf9bbb027 100644 (file)
@@ -911,6 +911,10 @@ struct rq {
 
        atomic_t                nr_iowait;
 
+#ifdef CONFIG_MEMBARRIER
+       int membarrier_state;
+#endif
+
 #ifdef CONFIG_SMP
        struct root_domain              *rd;
        struct sched_domain __rcu       *sd;
@@ -2438,3 +2442,33 @@ static inline bool sched_energy_enabled(void)
 static inline bool sched_energy_enabled(void) { return false; }
 
 #endif /* CONFIG_ENERGY_MODEL && CONFIG_CPU_FREQ_GOV_SCHEDUTIL */
+
+#ifdef CONFIG_MEMBARRIER
+/*
+ * The scheduler provides memory barriers required by membarrier between:
+ * - prior user-space memory accesses and store to rq->membarrier_state,
+ * - store to rq->membarrier_state and following user-space memory accesses.
+ * In the same way it provides those guarantees around store to rq->curr.
+ */
+static inline void membarrier_switch_mm(struct rq *rq,
+                                       struct mm_struct *prev_mm,
+                                       struct mm_struct *next_mm)
+{
+       int membarrier_state;
+
+       if (prev_mm == next_mm)
+               return;
+
+       membarrier_state = atomic_read(&next_mm->membarrier_state);
+       if (READ_ONCE(rq->membarrier_state) == membarrier_state)
+               return;
+
+       WRITE_ONCE(rq->membarrier_state, membarrier_state);
+}
+#else
+static inline void membarrier_switch_mm(struct rq *rq,
+                                       struct mm_struct *prev_mm,
+                                       struct mm_struct *next_mm)
+{
+}
+#endif