* [PATCH] SLOW_WORK: Fix the CONFIG_MODULES=n case
@ 2009-12-01 13:52 David Howells
2009-12-01 14:26 ` Ingo Molnar
2009-12-01 15:13 ` David Howells
0 siblings, 2 replies; 3+ messages in thread
From: David Howells @ 2009-12-01 13:52 UTC (permalink / raw)
To: torvalds, akpm, mingo
Cc: cluster-devel, nfsv4, linux-kernel, linux-cachefs, jens.axboe,
linux-fsdevel, linux-cifs-client
From: David Howells <dhowells@redhat.com>
Commits 3d7a641 ("SLOW_WORK: Wait for outstanding work items belonging to a
module to clear") introduced some code to make sure that all of a module's
slow-work items were complete before that module was removed, and commit
3bde31a ("SLOW_WORK: Allow a requeueable work item to sleep till the thread is
needed") further extended that, breaking it in the process if CONFIG_MODULES=n:
CC kernel/slow-work.o
kernel/slow-work.c: In function 'slow_work_execute':
kernel/slow-work.c:313: error: 'slow_work_thread_processing' undeclared (first use in this function)
kernel/slow-work.c:313: error: (Each undeclared identifier is reported only once
kernel/slow-work.c:313: error: for each function it appears in.)
kernel/slow-work.c: In function 'slow_work_wait_for_items':
kernel/slow-work.c:950: error: 'slow_work_unreg_sync_lock' undeclared (first use in this function)
kernel/slow-work.c:951: error: 'slow_work_unreg_wq' undeclared (first use in this function)
kernel/slow-work.c:961: error: 'slow_work_unreg_work_item' undeclared (first use in this function)
kernel/slow-work.c:974: error: 'slow_work_unreg_module' undeclared (first use in this function)
kernel/slow-work.c:977: error: 'slow_work_thread_processing' undeclared (first use in this function)
make[1]: *** [kernel/slow-work.o] Error 1
Fix this by:
(1) Extracting the bits of slow_work_execute() that are contingent on
CONFIG_MODULES, and the bits that should be, into inline functions and
placing them into the #ifdef'd section that defines the relevant variables
and adding stubs for moduleless kernels. This allows the removal of some
#ifdefs.
(2) #ifdef'ing out the contents of slow_work_wait_for_items() in moduleless
kernels.
The four functions related to handling module unloading synchronisation (and
their associated variables) could be offloaded into a separate .c file, but
each function is only used once and three of them are tiny, so doing so would
prevent them from being inlined.
Reported-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: David Howells <dhowells@redhat.com>
---
kernel/slow-work.c | 46 +++++++++++++++++++++++++++++-----------------
1 files changed, 29 insertions(+), 17 deletions(-)
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 */
}
/**
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] SLOW_WORK: Fix the CONFIG_MODULES=n case
2009-12-01 13:52 [PATCH] SLOW_WORK: Fix the CONFIG_MODULES=n case David Howells
@ 2009-12-01 14:26 ` Ingo Molnar
2009-12-01 15:13 ` David Howells
1 sibling, 0 replies; 3+ messages in thread
From: Ingo Molnar @ 2009-12-01 14:26 UTC (permalink / raw)
To: David Howells
Cc: nfsv4, linux-kernel, cluster-devel, torvalds, linux-cachefs,
jens.axboe, linux-fsdevel, akpm, linux-cifs-client
* 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
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] SLOW_WORK: Fix the CONFIG_MODULES=n case
2009-12-01 13:52 [PATCH] SLOW_WORK: Fix the CONFIG_MODULES=n case David Howells
2009-12-01 14:26 ` Ingo Molnar
@ 2009-12-01 15:13 ` David Howells
1 sibling, 0 replies; 3+ messages in thread
From: David Howells @ 2009-12-01 15:13 UTC (permalink / raw)
To: Ingo Molnar
Cc: cluster-devel, nfsv4, linux-kernel, torvalds, linux-cachefs,
jens.axboe, linux-fsdevel, akpm, linux-cifs-client
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
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2009-12-01 15:13 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-12-01 13:52 [PATCH] SLOW_WORK: Fix the CONFIG_MODULES=n case David Howells
2009-12-01 14:26 ` Ingo Molnar
2009-12-01 15:13 ` David Howells
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).