All of lore.kernel.org
 help / color / mirror / Atom feed
From: ecashin@cat.he.net
To: Andrew Morton <akpm@linux-foundation.org>
Cc: linux-kernel@vger.kernel.org, Ed Cashin <ecashin@coraid.com>
Subject: Re: [PATCH 02/14] aoe: kernel thread handles I/O completions for simple locking
Date: Sat, 25 Aug 2012 18:31:27 -0700	[thread overview]
Message-ID: <1345944687.24968@cat.he.net> (raw)
In-Reply-To: <20120824142257.cbfb21a6.akpm@linux-foundation.org>

On Fri, 24 Aug 2012 14:22:57 -0700, Andrew Morton wrote:

> On Fri, 17 Aug 2012 21:24:08 -0400
> Ed Cashin <ecashin@coraid.com> wrote:
...
> > +#ifdef PF_NOFREEZE
> 
> PF_NOFREEZE can never be undefined.
> 
> > +	current->flags |= PF_NOFREEZE;
> > +#endif
> > +	set_user_nice(current, -10);
> > +	sigfillset(&blocked);
> > +	sigprocmask(SIG_BLOCK, &blocked, NULL);
> > +	flush_signals(current);
> 
> This is a kernel thread - it shouldn't need to fiddle with signals.
> 
> > +	complete(&k->rendez);
> 
> That's odd.  Why do a complete() before we even start?  A code comment
> is needed if this is indeed correct.

There is a whole class of races that goes away when the code starting
a thread waits for the thread to be running before proceeding, and that's
what this rendezvous is for.  I've added a comment that will appear next
time I send the patchset.

(More comments below.)

> > +	do {
> > +		__set_current_state(TASK_UNINTERRUPTIBLE);
> 
> I think this statement is simply unneeded.
> 
> > +		spin_lock_irq(k->lock);
> > +		more = k->fn();
> > +		if (!more) {
> > +			add_wait_queue(k->waitq, &wait);
> > +			__set_current_state(TASK_INTERRUPTIBLE);
> > +		}
> > +		spin_unlock_irq(k->lock);
> > +		if (!more) {
> > +			schedule();
> > +			remove_wait_queue(k->waitq, &wait);
> > +		} else
> > +			cond_resched();
> 
> Here we can do a cond_resched() when in state TASK_INTERRUPTIBLE.  Such
> a schedule() will never return unless some other thread flips this task
> into state TASK_RUNNING.  But if another thread does that, we should
> have been on that waitqueue!
> 
> It seems all confused and racy.

When we do a cond_resched, it's only when "more" is non-zero, in which
case, we did not set the state to TASK_INTERRUPTIBLE.  I do like
your suggestions, though.

Please check out the (post-patchset) changes below that I plan to
incorporate into the patchset for resubmission, and let me know if
you see a race now that your suggestions have been incorporated.

It seems to work just as well in the testing I did with the changes
below incorporated.

diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index d91b8d0..97d05fa 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -1075,20 +1075,13 @@ kthread(void *vp)
 {
 	struct ktstate *k;
 	DECLARE_WAITQUEUE(wait, current);
-	sigset_t blocked;
 	int more;
 
 	k = vp;
-#ifdef PF_NOFREEZE
 	current->flags |= PF_NOFREEZE;
-#endif
 	set_user_nice(current, -10);
-	sigfillset(&blocked);
-	sigprocmask(SIG_BLOCK, &blocked, NULL);
-	flush_signals(current);
-	complete(&k->rendez);
+	complete(&k->rendez);	/* tell spawner we're running */
 	do {
-		__set_current_state(TASK_UNINTERRUPTIBLE);
 		spin_lock_irq(k->lock);
 		more = k->fn();
 		if (!more) {
@@ -1102,8 +1095,7 @@ kthread(void *vp)
 		} else
 			cond_resched();
 	} while (!kthread_should_stop());
-	__set_current_state(TASK_RUNNING);
-	complete(&k->rendez);
+	complete(&k->rendez);	/* tell spawner we're stopping */
 	return 0;
 }
 
@@ -1122,10 +1114,10 @@ aoe_ktstart(struct ktstate *k)
 	init_completion(&k->rendez);
 	task = kthread_run(kthread, k, k->name);
 	if (task == NULL || IS_ERR(task))
-		return -EFAULT;
+		return -ENOMEM;
 	k->task = task;
-	wait_for_completion(&k->rendez);
-	init_completion(&k->rendez);	/* for exit */
+	wait_for_completion(&k->rendez); /* allow kthread to start */
+	init_completion(&k->rendez);	/* for waiting for exit later */
 	return 0;
 }
 

  parent reply	other threads:[~2012-08-26  1:39 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-23 17:43 [PATCH 00/14] aoe driver v49 performance and usability improvements Ed Cashin
2012-08-18  1:18 ` [PATCH 01/14] aoe: for performance support larger packet payloads Ed Cashin
2012-08-23 20:32   ` Ed Cashin
2012-08-23 20:46   ` Ed Cashin
2012-08-24 21:11   ` Andrew Morton
2012-08-18  1:18 ` Ed Cashin
2012-08-18  1:24 ` [PATCH 02/14] aoe: kernel thread handles I/O completions for simple locking Ed Cashin
2012-08-24 21:22   ` Andrew Morton
2012-08-25  0:35     ` Ed Cashin
2012-08-26  1:31     ` ecashin [this message]
2012-08-18  1:26 ` [PATCH 03/14] aoe: become I/O request queue handler for increased user control Ed Cashin
2012-08-18  1:26 ` [PATCH 04/14] aoe: use a kernel thread for transmissions Ed Cashin
2012-08-18  1:27 ` [PATCH 05/14] aoe: use packets that work with the smallest-MTU local interface Ed Cashin
2012-08-18  1:27 ` [PATCH 06/14] aoe: failover remote interface based on aoe_deadsecs parameter Ed Cashin
2012-08-18  1:27 ` [PATCH 07/14] aoe: do revalidation steps in order Ed Cashin
2012-08-18  1:27 ` [PATCH 08/14] aoe: disallow unsupported AoE minor addresses Ed Cashin
2012-08-18  1:27 ` [PATCH 11/14] aoe: remove unused code and add cosmetic improvements Ed Cashin
2012-08-18  1:28 ` [PATCH 12/14] aoe: update internal version number to 49 Ed Cashin
2012-08-18  1:28 ` [PATCH 13/14] aoe: update copyright year in touched files Ed Cashin
2012-08-21 14:58 ` [PATCH 09/14] aoe: associate frames with the AoE storage target Ed Cashin
2012-08-21 15:07 ` [PATCH 10/14] aoe: increase net_device reference count while using it Ed Cashin
2012-08-23 17:36 ` [PATCH 14/14] aoe: update documentation with new URL and VM settings reference Ed Cashin
2012-08-24 23:57 ` [PATCH 00/14] aoe driver v49 performance and usability improvements Ed Cashin
  -- strict thread matches above, loose matches on Subject: below --
2012-08-28 12:53 Ed Cashin
2012-08-25 14:39 ` [PATCH 02/14] aoe: kernel thread handles I/O completions for simple locking Ed Cashin
2012-08-31 20:06   ` Andrew Morton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1345944687.24968@cat.he.net \
    --to=ecashin@cat.he.net \
    --cc=akpm@linux-foundation.org \
    --cc=ecashin@coraid.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.