Message ID | 25668.1259675528@redhat.com |
---|---|
State | New |
Headers | show |
* David Howells <dhowells@redhat.com> wrote: > @@ -943,6 +953,7 @@ EXPORT_SYMBOL(slow_work_register_user); > */ > static void slow_work_wait_for_items(struct module *module) > { > +#ifdef CONFIG_MODULES > DECLARE_WAITQUEUE(myself, current); > struct slow_work *work; > int loop; > @@ -989,6 +1000,7 @@ static void slow_work_wait_for_items(struct module *module) > > remove_wait_queue(&slow_work_unreg_wq, &myself); > mutex_unlock(&slow_work_unreg_sync_lock); > +#endif /* CONFIG_MODULES */ > } this slow_work_wait_for_items() function should move into the #ifdef block too. With that fixed it looks good to me for .33 (but i havent tested it): Acked-by: Ingo Molnar <mingo@elte.hu> In terms of .32 i guess it's OK too and the fix is needed - but i'd really not have done even the preceding changes - why again did we need /proc/slow_work_rq via 8fba10a and why did it have to happen right before the final kernel? If then it should have been done in debugfs - we dont need yet another /proc ABI. Also, a very small aesthetic detail: i think the title should use the 'slow-work: ' prefix, not 'SLOW_WORK: '. Thanks, Ingo
Ingo Molnar <mingo@elte.hu> wrote: > this slow_work_wait_for_items() function should move into the #ifdef > block too. I disagree: I want to keep the variable declaration blocks small; I'd rather not even put the inline functions in there that I did. I only did that because you wanted the #ifdef count reduced. > In terms of .32 i guess it's OK too and the fix is needed - but i'd really > not have done even the preceding changes - why again did we need > /proc/slow_work_rq via 8fba10a The slow_work_rq debugging interface is not strictly necessary, but it proved a useful debugging tool. I emailed Linus before I went on holiday and asked if he was willing to take these not-strictly-necessary patches on which other patches were built, or whether he'd prefer me to drop those patches and adjust the rest. > and why did it have to happen right before the final kernel? Because it did. That's when I finished my set of patches and published them before going on holiday for a week - and that in turn was related to when I came up with a better test case. Sometimes coincidences do happen. > If then it should have been done in debugfs - we dont need yet another > /proc ABI. Possibly. That just means we have a debugfs ABI instead of a proc ABI - it needs maintaining either way. On the other hand, it can be moved there easily and the docs changed, and doing so makes a reasonable amount of sense - except that debugfs isn't normally mounted by at least Fedora for some reason. David
diff --git a/kernel/slow-work.c b/kernel/slow-work.c index da94f3c..b5c17f1 100644 --- a/kernel/slow-work.c +++ b/kernel/slow-work.c @@ -109,6 +109,30 @@ static struct module *slow_work_unreg_module; static struct slow_work *slow_work_unreg_work_item; static DECLARE_WAIT_QUEUE_HEAD(slow_work_unreg_wq); static DEFINE_MUTEX(slow_work_unreg_sync_lock); + +static void slow_work_set_thread_processing(int id, struct slow_work *work) +{ + if (work) + slow_work_thread_processing[id] = work->owner; +} +static void slow_work_done_thread_processing(int id, struct slow_work *work) +{ + struct module *module = slow_work_thread_processing[id]; + + slow_work_thread_processing[id] = NULL; + smp_mb(); + if (slow_work_unreg_work_item == work || + slow_work_unreg_module == module) + wake_up_all(&slow_work_unreg_wq); +} +static void slow_work_clear_thread_processing(int id) +{ + slow_work_thread_processing[id] = NULL; +} +#else +static void slow_work_set_thread_processing(int id, struct slow_work *work) {} +static void slow_work_done_thread_processing(int id, struct slow_work *work) {} +static void slow_work_clear_thread_processing(int id) {} #endif /* @@ -197,9 +221,6 @@ static unsigned slow_work_calc_vsmax(void) */ static noinline bool slow_work_execute(int id) { -#ifdef CONFIG_MODULES - struct module *module; -#endif struct slow_work *work = NULL; unsigned vsmax; bool very_slow; @@ -236,10 +257,7 @@ static noinline bool slow_work_execute(int id) very_slow = false; /* avoid the compiler warning */ } -#ifdef CONFIG_MODULES - if (work) - slow_work_thread_processing[id] = work->owner; -#endif + slow_work_set_thread_processing(id, work); if (work) { slow_work_mark_time(work); slow_work_begin_exec(id, work); @@ -287,15 +305,7 @@ static noinline bool slow_work_execute(int id) /* sort out the race between module unloading and put_ref() */ slow_work_put_ref(work); - -#ifdef CONFIG_MODULES - module = slow_work_thread_processing[id]; - slow_work_thread_processing[id] = NULL; - smp_mb(); - if (slow_work_unreg_work_item == work || - slow_work_unreg_module == module) - wake_up_all(&slow_work_unreg_wq); -#endif + slow_work_done_thread_processing(id, work); return true; @@ -310,7 +320,7 @@ auto_requeue: else list_add_tail(&work->link, &slow_work_queue); spin_unlock_irq(&slow_work_queue_lock); - slow_work_thread_processing[id] = NULL; + slow_work_clear_thread_processing(id); return true; } @@ -943,6 +953,7 @@ EXPORT_SYMBOL(slow_work_register_user); */ static void slow_work_wait_for_items(struct module *module) { +#ifdef CONFIG_MODULES DECLARE_WAITQUEUE(myself, current); struct slow_work *work; int loop; @@ -989,6 +1000,7 @@ static void slow_work_wait_for_items(struct module *module) remove_wait_queue(&slow_work_unreg_wq, &myself); mutex_unlock(&slow_work_unreg_sync_lock); +#endif /* CONFIG_MODULES */ } /**