Currently, print nothing in place of [S] in report, which means
stacktrace of event context's start if the event is not an unlock thing
by typical lock but general event because it's not easy to specify the
point in a general way, where the event context has started from.
However, unfortunately it makes hard to interpret dept's report in that
case. So made it print the event requestor's stacktrace instead of the
event context's start, in place of [S] in report.
Signed-off-by: Byungchul Park <[email protected]>
---
include/linux/dept.h | 13 +++++++
kernel/dependency/dept.c | 83 ++++++++++++++++++++++++++++++++--------
2 files changed, 80 insertions(+), 16 deletions(-)
diff --git a/include/linux/dept.h b/include/linux/dept.h
index dea53ad5b356..6db23d77905e 100644
--- a/include/linux/dept.h
+++ b/include/linux/dept.h
@@ -145,6 +145,11 @@ struct dept_map {
*/
unsigned int wgen;
+ /*
+ * requestor for the event context to run
+ */
+ struct dept_stack *req_stack;
+
/*
* whether this map should be going to be checked or not
*/
@@ -486,7 +491,15 @@ struct dept_task {
* for subsystems that requires compact use of memory e.g. struct page
*/
struct dept_ext_wgen{
+ /*
+ * wait timestamp associated to this map
+ */
unsigned int wgen;
+
+ /*
+ * requestor for the event context to run
+ */
+ struct dept_stack *req_stack;
};
#define DEPT_TASK_INITIALIZER(t) \
diff --git a/kernel/dependency/dept.c b/kernel/dependency/dept.c
index fb33c3758c25..abf1cdab0615 100644
--- a/kernel/dependency/dept.c
+++ b/kernel/dependency/dept.c
@@ -129,6 +129,7 @@ static int dept_per_cpu_ready;
#define DEPT_INFO(s...) pr_warn("DEPT_INFO: " s)
static arch_spinlock_t dept_spin = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;
+static arch_spinlock_t dept_req_spin = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;
static arch_spinlock_t dept_pool_spin = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;
/*
@@ -1669,7 +1670,8 @@ static void add_wait(struct dept_class *c, unsigned long ip,
static bool add_ecxt(struct dept_map *m, struct dept_class *c,
unsigned long ip, const char *c_fn,
- const char *e_fn, int sub_l)
+ const char *e_fn, int sub_l,
+ struct dept_stack *req_stack)
{
struct dept_task *dt = dept_task();
struct dept_ecxt_held *eh;
@@ -1700,10 +1702,16 @@ static bool add_ecxt(struct dept_map *m, struct dept_class *c,
e->class = get_class(c);
e->ecxt_ip = ip;
- e->ecxt_stack = ip && rich_stack ? get_current_stack() : NULL;
e->event_fn = e_fn;
e->ecxt_fn = c_fn;
+ if (req_stack)
+ e->ecxt_stack = get_stack(req_stack);
+ else if (ip && rich_stack)
+ e->ecxt_stack = get_current_stack();
+ else
+ e->ecxt_stack = NULL;
+
eh = dt->ecxt_held + (dt->ecxt_held_pos++);
eh->ecxt = get_ecxt(e);
eh->map = m;
@@ -2147,6 +2155,7 @@ void dept_map_init(struct dept_map *m, struct dept_key *k, int sub_u,
m->sub_u = sub_u;
m->name = n;
m->wgen = 0U;
+ m->req_stack = NULL;
m->nocheck = !valid_key(k);
dept_exit_recursive(flags);
@@ -2181,6 +2190,7 @@ void dept_map_reinit(struct dept_map *m, struct dept_key *k, int sub_u,
m->name = n;
m->wgen = 0U;
+ m->req_stack = NULL;
dept_exit_recursive(flags);
}
@@ -2189,6 +2199,7 @@ EXPORT_SYMBOL_GPL(dept_map_reinit);
void dept_ext_wgen_init(struct dept_ext_wgen *ewg)
{
ewg->wgen = 0U;
+ ewg->req_stack = NULL;
}
void dept_map_copy(struct dept_map *to, struct dept_map *from)
@@ -2376,7 +2387,8 @@ static void __dept_wait(struct dept_map *m, unsigned long w_f,
*/
static void __dept_event(struct dept_map *m, unsigned long e_f,
unsigned long ip, const char *e_fn,
- bool sched_map, unsigned int wg)
+ bool sched_map, unsigned int wg,
+ struct dept_stack *req_stack)
{
struct dept_class *c;
struct dept_key *k;
@@ -2397,7 +2409,7 @@ static void __dept_event(struct dept_map *m, unsigned long e_f,
k = m->keys ?: &m->map_key;
c = check_new_class(&m->map_key, k, sub_id(m, e), m->name, sched_map);
- if (c && add_ecxt(m, c, 0UL, NULL, e_fn, 0)) {
+ if (c && add_ecxt(m, c, 0UL, "(event requestor)", e_fn, 0, req_stack)) {
do_event(m, c, wg, ip);
pop_ecxt(m, c);
}
@@ -2506,6 +2518,8 @@ EXPORT_SYMBOL_GPL(dept_stage_wait);
static void __dept_clean_stage(struct dept_task *dt)
{
+ if (dt->stage_m.req_stack)
+ put_stack(dt->stage_m.req_stack);
memset(&dt->stage_m, 0x0, sizeof(struct dept_map));
dt->stage_sched_map = false;
dt->stage_w_fn = NULL;
@@ -2571,6 +2585,7 @@ void dept_request_event_wait_commit(void)
*/
wg = atomic_inc_return(&wgen) ?: atomic_inc_return(&wgen);
WRITE_ONCE(dt->stage_m.wgen, wg);
+ dt->stage_m.req_stack = get_current_stack();
__dept_wait(&dt->stage_m, 1UL, ip, w_fn, 0, true, sched_map, timeout);
exit:
@@ -2602,6 +2617,8 @@ void dept_stage_event(struct task_struct *requestor, unsigned long ip)
*/
m = dt_req->stage_m;
sched_map = dt_req->stage_sched_map;
+ if (m.req_stack)
+ get_stack(m.req_stack);
__dept_clean_stage(dt_req);
/*
@@ -2611,8 +2628,12 @@ void dept_stage_event(struct task_struct *requestor, unsigned long ip)
if (!m.keys)
goto exit;
- __dept_event(&m, 1UL, ip, "try_to_wake_up", sched_map, m.wgen);
+ __dept_event(&m, 1UL, ip, "try_to_wake_up", sched_map, m.wgen,
+ m.req_stack);
exit:
+ if (m.req_stack)
+ put_stack(m.req_stack);
+
dept_exit(flags);
}
@@ -2692,7 +2713,7 @@ void dept_map_ecxt_modify(struct dept_map *m, unsigned long e_f,
k = m->keys ?: &m->map_key;
c = check_new_class(&m->map_key, k, sub_id(m, new_e), m->name, false);
- if (c && add_ecxt(m, c, new_ip, new_c_fn, new_e_fn, new_sub_l))
+ if (c && add_ecxt(m, c, new_ip, new_c_fn, new_e_fn, new_sub_l, NULL))
goto exit;
/*
@@ -2744,7 +2765,7 @@ void dept_ecxt_enter(struct dept_map *m, unsigned long e_f, unsigned long ip,
k = m->keys ?: &m->map_key;
c = check_new_class(&m->map_key, k, sub_id(m, e), m->name, false);
- if (c && add_ecxt(m, c, ip, c_fn, e_fn, sub_l))
+ if (c && add_ecxt(m, c, ip, c_fn, e_fn, sub_l, NULL))
goto exit;
missing_ecxt:
dt->missing_ecxt++;
@@ -2792,9 +2813,11 @@ EXPORT_SYMBOL_GPL(dept_ecxt_holding);
void dept_request_event(struct dept_map *m, struct dept_ext_wgen *ewg)
{
+ struct dept_task *dt = dept_task();
unsigned long flags;
unsigned int wg;
unsigned int *wg_p;
+ struct dept_stack **req_stack_p;
if (unlikely(!dept_working()))
return;
@@ -2802,12 +2825,18 @@ void dept_request_event(struct dept_map *m, struct dept_ext_wgen *ewg)
if (m->nocheck)
return;
- /*
- * Allow recursive entrance.
- */
- flags = dept_enter_recursive();
+ if (dt->recursive)
+ return;
- wg_p = ewg ? &ewg->wgen : &m->wgen;
+ flags = dept_enter();
+
+ if (ewg) {
+ wg_p = &ewg->wgen;
+ req_stack_p = &ewg->req_stack;
+ } else {
+ wg_p = &m->wgen;
+ req_stack_p = &m->req_stack;
+ }
/*
* Avoid zero wgen.
@@ -2815,7 +2844,13 @@ void dept_request_event(struct dept_map *m, struct dept_ext_wgen *ewg)
wg = atomic_inc_return(&wgen) ?: atomic_inc_return(&wgen);
WRITE_ONCE(*wg_p, wg);
- dept_exit_recursive(flags);
+ arch_spin_lock(&dept_req_spin);
+ if (*req_stack_p)
+ put_stack(*req_stack_p);
+ *req_stack_p = get_current_stack();
+ arch_spin_unlock(&dept_req_spin);
+
+ dept_exit(flags);
}
EXPORT_SYMBOL_GPL(dept_request_event);
@@ -2826,6 +2861,8 @@ void dept_event(struct dept_map *m, unsigned long e_f,
struct dept_task *dt = dept_task();
unsigned long flags;
unsigned int *wg_p;
+ struct dept_stack **req_stack_p;
+ struct dept_stack *req_stack;
if (unlikely(!dept_working()))
return;
@@ -2833,7 +2870,18 @@ void dept_event(struct dept_map *m, unsigned long e_f,
if (m->nocheck)
return;
- wg_p = ewg ? &ewg->wgen : &m->wgen;
+ if (ewg) {
+ wg_p = &ewg->wgen;
+ req_stack_p = &ewg->req_stack;
+ } else {
+ wg_p = &m->wgen;
+ req_stack_p = &m->req_stack;
+ }
+
+ arch_spin_lock(&dept_req_spin);
+ req_stack = *req_stack_p;
+ *req_stack_p = NULL;
+ arch_spin_unlock(&dept_req_spin);
if (dt->recursive) {
/*
@@ -2842,17 +2890,20 @@ void dept_event(struct dept_map *m, unsigned long e_f,
* handling the event. Disable it until the next.
*/
WRITE_ONCE(*wg_p, 0U);
+ if (req_stack)
+ put_stack(req_stack);
return;
}
flags = dept_enter();
-
- __dept_event(m, e_f, ip, e_fn, false, READ_ONCE(*wg_p));
+ __dept_event(m, e_f, ip, e_fn, false, READ_ONCE(*wg_p), req_stack);
/*
* Keep the map diabled until the next sleep.
*/
WRITE_ONCE(*wg_p, 0U);
+ if (req_stack)
+ put_stack(req_stack);
dept_exit(flags);
}
--
2.17.1
Hi Byungchul,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 0dd3ee31125508cd67f7e7172247f05b7fd1753a]
url: https://github.com/intel-lab-lkp/linux/commits/Byungchul-Park/llist-Move-llist_-head-node-definition-to-types-h/20240124-200243
base: 0dd3ee31125508cd67f7e7172247f05b7fd1753a
patch link: https://lore.kernel.org/r/20240124115938.80132-26-byungchul%40sk.com
patch subject: [PATCH v11 25/26] dept: Print event context requestor's stacktrace on report
config: microblaze-allmodconfig (https://download.01.org/0day-ci/archive/20240128/[email protected]/config)
compiler: microblaze-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240128/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All warnings (new ones prefixed by >>):
drivers/gpu/drm/tests/drm_exec_test.c: In function 'test_prepare_array':
>> drivers/gpu/drm/tests/drm_exec_test.c:171:1: warning: the frame size of 1028 bytes is larger than 1024 bytes [-Wframe-larger-than=]
171 | }
| ^
vim +171 drivers/gpu/drm/tests/drm_exec_test.c
9710631cc8f367 Christian K?nig 2022-04-13 149
9710631cc8f367 Christian K?nig 2022-04-13 150 static void test_prepare_array(struct kunit *test)
9710631cc8f367 Christian K?nig 2022-04-13 151 {
0f249678fef433 Arthur Grillo 2023-07-31 152 struct drm_exec_priv *priv = test->priv;
9710631cc8f367 Christian K?nig 2022-04-13 153 struct drm_gem_object gobj1 = { };
9710631cc8f367 Christian K?nig 2022-04-13 154 struct drm_gem_object gobj2 = { };
9710631cc8f367 Christian K?nig 2022-04-13 155 struct drm_gem_object *array[] = { &gobj1, &gobj2 };
9710631cc8f367 Christian K?nig 2022-04-13 156 struct drm_exec exec;
9710631cc8f367 Christian K?nig 2022-04-13 157 int ret;
9710631cc8f367 Christian K?nig 2022-04-13 158
0f249678fef433 Arthur Grillo 2023-07-31 159 drm_gem_private_object_init(priv->drm, &gobj1, PAGE_SIZE);
0f249678fef433 Arthur Grillo 2023-07-31 160 drm_gem_private_object_init(priv->drm, &gobj2, PAGE_SIZE);
9710631cc8f367 Christian K?nig 2022-04-13 161
9710631cc8f367 Christian K?nig 2022-04-13 162 drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
9710631cc8f367 Christian K?nig 2022-04-13 163 drm_exec_until_all_locked(&exec)
9710631cc8f367 Christian K?nig 2022-04-13 164 ret = drm_exec_prepare_array(&exec, array, ARRAY_SIZE(array),
9710631cc8f367 Christian K?nig 2022-04-13 165 1);
9710631cc8f367 Christian K?nig 2022-04-13 166 KUNIT_EXPECT_EQ(test, ret, 0);
9710631cc8f367 Christian K?nig 2022-04-13 167 drm_exec_fini(&exec);
806fd6d005ad7a Danilo Krummrich 2023-08-10 168
806fd6d005ad7a Danilo Krummrich 2023-08-10 169 drm_gem_private_object_fini(&gobj1);
806fd6d005ad7a Danilo Krummrich 2023-08-10 170 drm_gem_private_object_fini(&gobj2);
9710631cc8f367 Christian K?nig 2022-04-13 @171 }
9710631cc8f367 Christian K?nig 2022-04-13 172
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki