diff --git a/include/linux/dept.h b/include/linux/dept.h
index e3e68ef47b9e..827ccc1890d1 100644
--- a/include/linux/dept.h
+++ b/include/linux/dept.h
@@ -129,6 +129,13 @@ struct dept_wait_hist {
unsigned int ctxt_id;
};
+/*
+ * for subsystems that requires compact use of memory e.g. struct page
+ */
+struct dept_ext_wgen {
+ unsigned int wgen;
+};
+
void dept_on(void);
void dept_off(void);
void dept_init(void);@@ -138,6 +145,7 @@ void dept_free_range(void *start, unsigned int sz);
void dept_map_init(struct dept_map *m, struct dept_key *k, int sub_u, const char *n);
void dept_map_reinit(struct dept_map *m, struct dept_key *k, int sub_u, const char *n);
+void dept_ext_wgen_init(struct dept_ext_wgen *ewg);
void dept_map_copy(struct dept_map *to, struct dept_map *from);
void dept_wait(struct dept_map *m, unsigned long w_f, unsigned long ip, const char *w_fn, int sub_l, long timeout);
void dept_stage_wait(struct dept_map *m, struct dept_key *k, unsigned long ip, const char *w_fn, long timeout);
@@ -146,8 +154,8 @@ void dept_clean_stage(void);
void dept_ttwu_stage_wait(struct task_struct *t, unsigned long ip);
void dept_ecxt_enter(struct dept_map *m, unsigned long e_f, unsigned long ip, const char *c_fn, const char *e_fn, int sub_l);
bool dept_ecxt_holding(struct dept_map *m, unsigned long e_f);
-void dept_request_event(struct dept_map *m);
-void dept_event(struct dept_map *m, unsigned long e_f, unsigned long ip, const char *e_fn);
+void dept_request_event(struct dept_map *m, struct dept_ext_wgen *ewg);
+void dept_event(struct dept_map *m, unsigned long e_f, unsigned long ip, const char *e_fn, struct dept_ext_wgen *ewg);
void dept_ecxt_exit(struct dept_map *m, unsigned long e_f, unsigned long ip);
void dept_sched_enter(void);
void dept_sched_exit(void);
@@ -174,6 +182,7 @@ void dept_hardirqs_off(void);
#else /* !CONFIG_DEPT */
struct dept_key { };
struct dept_map { };
+struct dept_ext_wgen { };
#define DEPT_MAP_INITIALIZER(n, k) { }
@@ -186,6 +195,7 @@ struct dept_map { };
#define dept_map_init(m, k, su, n) do { (void)(n); (void)(k); } while (0)
#define dept_map_reinit(m, k, su, n) do { (void)(n); (void)(k); } while (0)
+#define dept_ext_wgen_init(wg) do { } while (0)
#define dept_map_copy(t, f) do { } while (0)
#define dept_wait(m, w_f, ip, w_fn, sl, t) do { (void)(w_fn); } while (0)
#define dept_stage_wait(m, k, ip, w_fn, t) do { (void)(k); (void)(w_fn); } while (0)@@ -194,8 +204,8 @@ struct dept_map { };
#define dept_ttwu_stage_wait(t, ip) do { } while (0)
#define dept_ecxt_enter(m, e_f, ip, c_fn, e_fn, sl) do { (void)(c_fn); (void)(e_fn); } while (0)
#define dept_ecxt_holding(m, e_f) false
-#define dept_request_event(m) do { } while (0)
-#define dept_event(m, e_f, ip, e_fn) do { (void)(e_fn); } while (0)
+#define dept_request_event(m, wg) do { } while (0)
+#define dept_event(m, e_f, ip, e_fn, wg) do { (void)(e_fn); } while (0)
#define dept_ecxt_exit(m, e_f, ip) do { } while (0)
#define dept_sched_enter() do { } while (0)
#define dept_sched_exit() do { } while (0)diff --git a/include/linux/dept_sdt.h b/include/linux/dept_sdt.h
index 14917df0cc30..9cd70affaf35 100644
--- a/include/linux/dept_sdt.h
+++ b/include/linux/dept_sdt.h
@@ -25,7 +25,7 @@
#define sdt_wait_timeout(m, t) \
do { \
- dept_request_event(m); \
+ dept_request_event(m, NULL); \
dept_wait(m, 1UL, _THIS_IP_, __func__, 0, t); \
} while (0)
#define sdt_wait(m) sdt_wait_timeout(m, -1L)@@ -49,9 +49,9 @@
#define sdt_might_sleep_end() dept_clean_stage()
#define sdt_ecxt_enter(m) dept_ecxt_enter(m, 1UL, _THIS_IP_, "start", "event", 0)
-#define sdt_event(m) dept_event(m, 1UL, _THIS_IP_, __func__)
+#define sdt_event(m) dept_event(m, 1UL, _THIS_IP_, __func__, NULL)
#define sdt_ecxt_exit(m) dept_ecxt_exit(m, 1UL, _THIS_IP_)
-#define sdt_request_event(m) dept_request_event(m)
+#define sdt_request_event(m) dept_request_event(m, NULL)
#else /* !CONFIG_DEPT */
#define sdt_map_init(m) do { } while (0)
#define sdt_map_init_key(m, k) do { (void)(k); } while (0)diff --git a/kernel/dependency/dept.c b/kernel/dependency/dept.c
index 5ef85977e631..e425d3ab05e5 100644
--- a/kernel/dependency/dept.c
+++ b/kernel/dependency/dept.c
@@ -2172,6 +2172,11 @@ void dept_map_reinit(struct dept_map *m, struct dept_key *k, int sub_u,
}
EXPORT_SYMBOL_GPL(dept_map_reinit);
+void dept_ext_wgen_init(struct dept_ext_wgen *ewg)
+{
+ ewg->wgen = 0U;
+}
+
void dept_map_copy(struct dept_map *to, struct dept_map *from)
{
if (unlikely(!dept_working())) {@@ -2355,7 +2360,7 @@ static void __dept_wait(struct dept_map *m, unsigned long w_f,
*/
static void __dept_event(struct dept_map *m, struct dept_map *real_m,
unsigned long e_f, unsigned long ip, const char *e_fn,
- bool sched_map)
+ bool sched_map, unsigned int wg)
{
struct dept_class *c;
struct dept_key *k;@@ -2377,7 +2382,7 @@ static void __dept_event(struct dept_map *m, struct dept_map *real_m,
c = check_new_class(&m->map_key, k, sub_id(m, e), m->name, sched_map);
if (c)
- do_event(m, real_m, c, READ_ONCE(m->wgen), ip, e_fn);
+ do_event(m, real_m, c, wg, ip, e_fn);
}
void dept_wait(struct dept_map *m, unsigned long w_f,
@@ -2602,7 +2607,7 @@ void dept_ttwu_stage_wait(struct task_struct *requestor, unsigned long ip)
if (!m.keys)
goto exit;
- __dept_event(&m, real_m, 1UL, ip, "try_to_wake_up", sched_map);
+ __dept_event(&m, real_m, 1UL, ip, "try_to_wake_up", sched_map, m.wgen);
exit:
dept_exit(flags);
}
@@ -2781,10 +2786,11 @@ bool dept_ecxt_holding(struct dept_map *m, unsigned long e_f)
}
EXPORT_SYMBOL_GPL(dept_ecxt_holding);
-void dept_request_event(struct dept_map *m)
+void dept_request_event(struct dept_map *m, struct dept_ext_wgen *ewg)
{
unsigned long flags;
unsigned int wg;
+ unsigned int *wg_p;
if (unlikely(!dept_working()))
return;@@ -2797,18 +2803,22 @@ void dept_request_event(struct dept_map *m)
*/
flags = dept_enter_recursive();
+ wg_p = ewg ? &ewg->wgen : &m->wgen;
+
wg = next_wgen();
- WRITE_ONCE(m->wgen, wg);
+ WRITE_ONCE(*wg_p, wg);
dept_exit_recursive(flags);
}
EXPORT_SYMBOL_GPL(dept_request_event);
void dept_event(struct dept_map *m, unsigned long e_f,
- unsigned long ip, const char *e_fn)
+ unsigned long ip, const char *e_fn,
+ struct dept_ext_wgen *ewg)
{
struct dept_task *dt = dept_task();
unsigned long flags;
+ unsigned int *wg_p;
if (unlikely(!dept_working()))
return;@@ -2816,24 +2826,26 @@ void dept_event(struct dept_map *m, unsigned long e_f,
if (m->nocheck)
return;
+ wg_p = ewg ? &ewg->wgen : &m->wgen;
+
if (dt->recursive) {
/*
* Dept won't work with this even though an event
* context has been asked. Don't make it confused at
* handling the event. Disable it until the next.
*/
- WRITE_ONCE(m->wgen, 0U);
+ WRITE_ONCE(*wg_p, 0U);
return;
}
flags = dept_enter();
- __dept_event(m, m, e_f, ip, e_fn, false);
+ __dept_event(m, m, e_f, ip, e_fn, false, READ_ONCE(*wg_p));
/*
* Keep the map diabled until the next sleep.
*/
- WRITE_ONCE(m->wgen, 0U);
+ WRITE_ONCE(*wg_p, 0U);
dept_exit(flags);
}--
2.17.1