With multi event sites for a single wait, dept allows to skip tracking an event that is recoverable by other recover paths.
Introduce an API, event_site(), to skip tracking the event in the case. Signed-off-by: Byungchul Park <byungc...@sk.com> --- include/linux/dept.h | 30 ++++++++++++++++++++++++++++++ include/linux/sched.h | 6 ++++++ kernel/dependency/dept.c | 20 ++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/include/linux/dept.h b/include/linux/dept.h index a97f34d62468..b2292587c1cc 100644 --- a/include/linux/dept.h +++ b/include/linux/dept.h @@ -492,6 +492,31 @@ extern void dept_task_exit(struct task_struct *t); extern void dept_free_range(void *start, unsigned int sz); extern void dept_mark_event_site_used(void *start, void *end); +extern void disable_event_track(void); +extern void enable_event_track(void); + +#define event_site(es, evt_func, ...) \ +do { \ + unsigned long _flags; \ + bool _disable; \ + \ + local_irq_save(_flags); \ + dept_event_site_used(es); \ + /* \ + * If !list_empty(&(es)->dept_head), the event site can be \ + * recovered by others. Do not track event dependency if so. \ + */ \ + _disable = !list_empty(&(es)->dep_head); \ + if (_disable) \ + disable_event_track(); \ + \ + evt_func(__VA_ARGS__); \ + \ + if (_disable) \ + enable_event_track(); \ + local_irq_restore(_flags); \ +} while (0) + extern void dept_map_init(struct dept_map *m, struct dept_key *k, int sub_u, const char *n); extern void dept_map_reinit(struct dept_map *m, struct dept_key *k, int sub_u, const char *n); extern void dept_ext_wgen_init(struct dept_ext_wgen *ewg); @@ -555,6 +580,11 @@ struct dept_event_site { }; #define dept_task_exit(t) do { } while (0) #define dept_free_range(s, sz) do { } while (0) #define dept_mark_event_site_used(s, e) do { } while (0) +#define event_site(es, evt_func, ...) \ +do { \ + (void)(es); \ + evt_func(__VA_ARGS__); \ +} while (0) #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) diff --git a/include/linux/sched.h b/include/linux/sched.h index 43927e61921b..44a77b7116b7 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -873,6 +873,11 @@ struct dept_task { */ int missing_ecxt; + /* + * not to track events + */ + int disable_event_track_cnt; + /* * for tracking IRQ-enable state */ @@ -910,6 +915,7 @@ struct dept_task { .stage_wait_stack = NULL, \ .stage_lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED,\ .missing_ecxt = 0, \ + .disable_event_track_cnt = 0, \ .hardirqs_enabled = false, \ .softirqs_enabled = false, \ .task_exit = false, \ diff --git a/kernel/dependency/dept.c b/kernel/dependency/dept.c index bd46c2ce84eb..03d6c057cdc5 100644 --- a/kernel/dependency/dept.c +++ b/kernel/dependency/dept.c @@ -2585,6 +2585,23 @@ static void __dept_wait(struct dept_map *m, unsigned long w_f, } } +void disable_event_track(void) +{ + dept_task()->disable_event_track_cnt++; +} +EXPORT_SYMBOL_GPL(disable_event_track); + +void enable_event_track(void) +{ + dept_task()->disable_event_track_cnt--; +} +EXPORT_SYMBOL_GPL(enable_event_track); + +static bool event_track_disabled(void) +{ + return !!dept_task()->disable_event_track_cnt; +} + /* * Called between dept_enter() and dept_exit(). */ @@ -2597,6 +2614,9 @@ static void __dept_event(struct dept_map *m, struct dept_map *real_m, struct dept_key *k; int e; + if (event_track_disabled()) + return; + e = find_first_bit(&e_f, DEPT_MAX_SUBCLASSES_EVT); if (DEPT_WARN_ON(e >= DEPT_MAX_SUBCLASSES_EVT)) -- 2.17.1