diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h
index 8450e18a87c2..638b1b402d12 100644
--- a/include/linux/mmu_notifier.h
+++ b/include/linux/mmu_notifier.h
@@ -429,6 +429,14 @@ static inline int mmu_notifier_test_young(struct mm_struct *mm,
return 0;
}
+#ifdef CONFIG_DEPT
+void mmu_notifier_invalidate_dept_ecxt_start(struct mmu_notifier_range *range);
+void mmu_notifier_invalidate_dept_ecxt_end(struct mmu_notifier_range *range);
+#else
+static inline void mmu_notifier_invalidate_dept_ecxt_start(struct mmu_notifier_range *range) {}
+static inline void mmu_notifier_invalidate_dept_ecxt_end(struct mmu_notifier_range *range) {}
+#endif
+
static inline void
mmu_notifier_invalidate_range_start(struct mmu_notifier_range *range)
{@@ -440,6 +448,12 @@ mmu_notifier_invalidate_range_start(struct mmu_notifier_range *range)
__mmu_notifier_invalidate_range_start(range);
}
lock_map_release(&__mmu_notifier_invalidate_range_start_map);
+
+ /*
+ * From now on, waiters could be there by this start until
+ * mmu_notifier_invalidate_range_end().
+ */
+ mmu_notifier_invalidate_dept_ecxt_start(range);
}
/*
@@ -460,6 +474,12 @@ mmu_notifier_invalidate_range_start_nonblock(struct mmu_notifier_range *range)
ret = __mmu_notifier_invalidate_range_start(range);
}
lock_map_release(&__mmu_notifier_invalidate_range_start_map);
+
+ /*
+ * From now on, waiters could be there by this start until
+ * mmu_notifier_invalidate_range_end().
+ */
+ mmu_notifier_invalidate_dept_ecxt_start(range);
return ret;
}
@@ -471,6 +491,12 @@ mmu_notifier_invalidate_range_end(struct mmu_notifier_range *range)
if (mm_has_notifiers(range->mm))
__mmu_notifier_invalidate_range_end(range);
+
+ /*
+ * The event context that has been started by
+ * mmu_notifier_invalidate_range_start() ends.
+ */
+ mmu_notifier_invalidate_dept_ecxt_end(range);
}
static inline void mmu_notifier_arch_invalidate_secondary_tlbs(struct mm_struct *mm,
diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c
index a6cdf3674bdc..10c3420b3901 100644
--- a/mm/mmu_notifier.c
+++ b/mm/mmu_notifier.c
@@ -46,6 +46,7 @@ struct mmu_notifier_subscriptions {
unsigned long active_invalidate_ranges;
struct rb_root_cached itree;
wait_queue_head_t wq;
+ struct dept_map dmap;
struct hlist_head deferred_list;
};
@@ -165,6 +166,25 @@ static void mn_itree_inv_end(struct mmu_notifier_subscriptions *subscriptions)
wake_up_all(&subscriptions->wq);
}
+#ifdef CONFIG_DEPT
+void mmu_notifier_invalidate_dept_ecxt_start(struct mmu_notifier_range *range)
+{
+ struct mmu_notifier_subscriptions *subscriptions =
+ range->mm->notifier_subscriptions;
+
+ if (subscriptions)
+ sdt_ecxt_enter(&subscriptions->dmap);
+}
+void mmu_notifier_invalidate_dept_ecxt_end(struct mmu_notifier_range *range)
+{
+ struct mmu_notifier_subscriptions *subscriptions =
+ range->mm->notifier_subscriptions;
+
+ if (subscriptions)
+ sdt_ecxt_exit(&subscriptions->dmap);
+}
+#endif
+
/**
* mmu_interval_read_begin - Begin a read side critical section against a VA
* range@@ -246,9 +266,12 @@ mmu_interval_read_begin(struct mmu_interval_notifier *interval_sub)
*/
lock_map_acquire(&__mmu_notifier_invalidate_range_start_map);
lock_map_release(&__mmu_notifier_invalidate_range_start_map);
- if (is_invalidating)
+ if (is_invalidating) {
+ sdt_might_sleep_start(&subscriptions->dmap);
wait_event(subscriptions->wq,
READ_ONCE(subscriptions->invalidate_seq) != seq);
+ sdt_might_sleep_end();
+ }
/*
* Notice that mmu_interval_read_retry() can already be true at this@@ -624,6 +647,7 @@ int __mmu_notifier_register(struct mmu_notifier *subscription,
INIT_HLIST_HEAD(&subscriptions->list);
spin_lock_init(&subscriptions->lock);
+ sdt_map_init(&subscriptions->dmap);
subscriptions->invalidate_seq = 2;
subscriptions->itree = RB_ROOT_CACHED;
init_waitqueue_head(&subscriptions->wq);
@@ -1069,9 +1093,12 @@ void mmu_interval_notifier_remove(struct mmu_interval_notifier *interval_sub)
*/
lock_map_acquire(&__mmu_notifier_invalidate_range_start_map);
lock_map_release(&__mmu_notifier_invalidate_range_start_map);
- if (seq)
+ if (seq) {
+ sdt_might_sleep_start(&subscriptions->dmap);
wait_event(subscriptions->wq,
mmu_interval_seq_released(subscriptions, seq));
+ sdt_might_sleep_end();
+ }
/* pairs with mmgrab in mmu_interval_notifier_insert() */
mmdrop(mm);--
2.17.1