All of lore.kernel.org
 help / color / mirror / Atom feed
From: Srivatsa Vaddagiri <vatsa@in.ibm.com>
To: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Gautham R Shenoy <ego@in.ibm.com>,
	akpm@linux-foundation.org, paulmck@us.ibm.com,
	torvalds@linux-foundation.org, linux-kernel@vger.kernel.org,
	"Rafael J. Wysocki" <rjw@sisk.pl>,
	mingo@elte.hu, dipankar@in.ibm.com, dino@in.ibm.com,
	masami.hiramatsu.pt@hitachi.com
Subject: Re: [PATCH 7/8] Clean up workqueue.c with respect to the freezer based cpu-hotplug
Date: Tue, 3 Apr 2007 19:29:19 +0530	[thread overview]
Message-ID: <20070403135919.GB32444@in.ibm.com> (raw)
In-Reply-To: <20070403114729.GA776@tv-sign.ru>

On Tue, Apr 03, 2007 at 03:47:29PM +0400, Oleg Nesterov wrote:
> I still think that wait_to_die + bind_cpu is unneeded complication.
> Why can't we do the following:
> 
> 	static int worker_thread(void *__cwq)
> 	{
> 		...
> 
> 		for (;;) {
> 			try_to_freeze();
> 
> 			prepare_to_wait(&cwq->more_work, &wait, TASK_INTERRUPTIBLE);
> 			if (!kthread_should_stop() && list_empty(&cwq->worklist))
> 				schedule();
> 			finish_wait(&cwq->more_work, &wait);
> 
> 			if (kthread_should_stop(cwq))
> 				break;
> 
> 			run_workqueue(cwq);
> 		}
> 
> 		return 0;
> 	}
> 
> ?

cleanup_workqueue_thread (in Gautham's patches) does this:

	thaw_process()
	kthread_stop()

There is a chance that after thaw_process() [but before we have posted
the kthread_stop], worker thread can come out of the refrigerator and start
running run_workqueue() - that will simply prolong the subsequent
kthread_stop() and the system freeze time.

We could do what you are suggesting if the thaw_process() part was
integrated into kthread_stop() code [basically thaw_process after
setting the kthread_stop_info.k flag].

> >  void fastcall flush_workqueue(struct workqueue_struct *wq)
> >  {
> > -	const cpumask_t *cpu_map = wq_cpu_map(wq);
> >  	int cpu;
> >
> >  	might_sleep();
> > -	for_each_cpu_mask(cpu, *cpu_map)
> > +	for_each_online_cpu(cpu)
> >  		flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, cpu));
> >  }
> 
> Hm... I can't understand this change. I believe it is wrong.

Why?

> > -		for_each_possible_cpu(cpu) {
> > +		for_each_online_cpu(cpu) {
> 
> This is wrong. CPU_UP_PREPARE doesn't call init_cpu_workqueue().
> Easy to fix, but I personally think is is better to initialize
> the whole cpu_possible_map.

I tend to agree yes.

> >  static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)

[snip]

> > -	if (alive) {
> >  		thaw_process(cwq->thread);
> > -		wait_for_completion(&barr.done);
> > -
> > -		while (unlikely(cwq->status != CWQ_STOPPED))
> > -			cpu_relax();
> > -		/*
> > -		 * Wait until cwq->thread unlocks cwq->lock,
> > -		 * it won't touch *cwq after that.
> > -		 */
> > -		smp_rmb();
> > +		kthread_stop(cwq->thread);
> >  		cwq->thread = NULL;
> > -		spin_unlock_wait(&cwq->lock);
> >  	}
> >  }
> 
> Deadlockable. Suppose that the freezing is in progress, cwq->thread is not
> frozen yet. cleanup_workqueue_thread() calls thaw_process(cwq->thread),
> then cwq->thread() goes to refrigerator, kthread_stop() blocks forever.

Good catch! Can cleanup_workqueue_thread take some mutex to serialize
with freezer here (say freezer_mutex)?

Or better, since this seems to be a general problem for anyone who wants to do a
kthread_stop, how abt modifying kthread_stop like below:

kthread_stop(p)
{
	int old_exempt_flags;

	task_lock(p);
	old_exempt_flags = p->flags;
	p->flags |= PFE_ALL;	/* Exempt 'p' from being frozen? */
	task_unlock(p);

	kthread_stop_info.k = p;
	thaw_process(p);

	wait_for_completion();

}

Marking 'p' as exempt shouldn't be a problem because freezer would wait
on the thread doing kthread_stop() anyway before declaring system as
frozen.

> > +static void take_over_work(struct workqueue_struct *wq, unsigned int cpu)
> > +{
> > +	struct cpu_workqueue_struct *cwq = per_cpu_ptr(wq->cpu_wq, cpu);
> > +	struct list_head list;
> > +	struct work_struct *work;
> > +
> > +	spin_lock_irq(&cwq->lock);
> 
> This CPU is dead (or cancelled), we don't need cwq->lock.

yeah ..


> 
> >  static int __devinit workqueue_cpu_callback(struct notifier_block *nfb,
> >  						unsigned long action,
> >  						void *hcpu)
> > @@ -782,11 +768,6 @@ static int __devinit workqueue_cpu_callb
> >  	struct cpu_workqueue_struct *cwq;
> >  	struct workqueue_struct *wq;
> >
> > -	switch (action) {
> > -	case CPU_UP_PREPARE:
> > -		cpu_set(cpu, cpu_populated_map);
> > -	}
> > -
> >  	mutex_lock(&workqueue_mutex);
> >  	list_for_each_entry(wq, &workqueues, list) {
> >  		cwq = per_cpu_ptr(wq->cpu_wq, cpu);
> > @@ -799,6 +780,7 @@ static int __devinit workqueue_cpu_callb
> >  			return NOTIFY_BAD;
> >
> >  		case CPU_ONLINE:
> > +			kthread_bind(cwq->thread, cpu);
> >  			wake_up_process(cwq->thread);
> >  			break;
> >
> > @@ -806,6 +788,7 @@ static int __devinit workqueue_cpu_callb
> >  			if (cwq->thread)
> >  				wake_up_process(cwq->thread);
> >  		case CPU_DEAD:
> > +			take_over_work(wq, cpu);
> >  			cleanup_workqueue_thread(cwq, cpu);
> >  			break;
> >  		}
> 
> This means that the work_struct on single_threaded wq can't use any of
> 
> 	__create_workqueue()
> 	destroy_workqueue()
> 	flush_workqueue()
> 	cancel_work_sync()

The workqueue_mutex() should serialize these with workqueue_cpu_callback() to 
an extent, but  ..

> , they are all racy wrt workqueue_cpu_callback(), and we don't freeze
> single_threaded workqueues. This is bad.
> 
> Probaly we should:
> 
> 	- freeze all workqueues, even the single_threaded ones.

Yes I agree, we should target freezing everybody here. It feels much
safer that way!

The only dependency I have seen is stop_machine() called after processes
are frozen. It needs the services of a workqueue to create kthreads. We
need to atleast exempt that worker thread from being frozen. Hopefully
the list of such non-freezable singlethreaded workqueues will be tiny
enough for us to audit time-to-time.

> 	- helper_init() explicitely does __create_workqueue(FE_ALL).
> 	  this means that we should never use the functions above
> 	  with this workqueue.

Ok you seem to have covered what I went out to say above! 

Thx for your review so far ..

-- 
Regards,
vatsa

  reply	other threads:[~2007-04-03 13:51 UTC|newest]

Thread overview: 70+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-04-02  5:34 [RFC] Cpu-hotplug: Using the Process Freezer (try2) Gautham R Shenoy
2007-04-02  5:37 ` [PATCH 1/8] Enhance process freezer interface for usage beyond software suspend Gautham R Shenoy
2007-04-02 13:56   ` Pavel Machek
2007-04-02 20:48     ` Rafael J. Wysocki
2007-04-02 20:51       ` Pavel Machek
2007-04-06 14:34         ` Rafael J. Wysocki
2007-04-06 22:20           ` Nigel Cunningham
2007-04-07  9:33             ` Rafael J. Wysocki
2007-04-07  9:47               ` Nigel Cunningham
2007-04-09  3:04         ` Gautham R Shenoy
2007-04-03  7:59       ` Gautham R Shenoy
2007-04-05  9:46   ` Oleg Nesterov
2007-04-05 10:59     ` Gautham R Shenoy
2007-04-05 11:30       ` Oleg Nesterov
2007-04-02  5:37 ` [PATCH 2/8] Make process freezer reentrant Gautham R Shenoy
2007-04-05  9:53   ` Oleg Nesterov
2007-04-05 10:19     ` Gautham R Shenoy
2007-04-02  5:38 ` [PATCH 3/8] Use process freezer for cpu-hotplug Gautham R Shenoy
2007-04-05 10:53   ` Oleg Nesterov
2007-04-05 12:14     ` Gautham R Shenoy
2007-04-05 13:34       ` Oleg Nesterov
2007-04-06 17:27   ` Nathan Lynch
2007-04-06 17:34     ` Ingo Molnar
2007-04-06 17:47       ` Nathan Lynch
2007-04-06 22:22         ` Nigel Cunningham
2007-04-14 18:48       ` Pavel Machek
2007-04-02  5:39 ` [PATCH 4/8] Rip out lock_cpu_hotplug() Gautham R Shenoy
2007-04-02  5:40 ` [PATCH 5/8] __cpu_up: use singlethreaded workqueue Gautham R Shenoy
2007-04-05 12:08   ` Oleg Nesterov
2007-04-02  5:41 ` [PATCH 6/8] Make non-singlethreaded workqueues freezeable by default Gautham R Shenoy
2007-04-05 11:57   ` Oleg Nesterov
2007-04-05 20:06     ` Andrew Morton
2007-04-02  5:42 ` [PATCH 7/8] Clean up workqueue.c with respect to the freezer based cpu-hotplug Gautham R Shenoy
2007-04-03 11:47   ` Oleg Nesterov
2007-04-03 13:59     ` Srivatsa Vaddagiri [this message]
2007-04-03 15:03       ` Oleg Nesterov
2007-04-03 17:18         ` Srivatsa Vaddagiri
2007-04-04 15:28           ` Oleg Nesterov
2007-04-04 17:49             ` Srivatsa Vaddagiri
2007-04-05 12:20               ` Oleg Nesterov
2007-04-12  2:22           ` Srivatsa Vaddagiri
2007-04-12 10:01             ` Gautham R Shenoy
2007-04-12 16:00             ` Oleg Nesterov
2007-04-13  9:46               ` Gautham R Shenoy
2007-04-02  5:42 ` [PATCH 8/8] Make kernel threads freezeable for cpu-hotplug Gautham R Shenoy
2007-04-02  6:16 ` [RFC] Cpu-hotplug: Using the Process Freezer (try2) Ingo Molnar
2007-04-02  9:28   ` Srivatsa Vaddagiri
2007-04-02 11:18     ` Ingo Molnar
2007-04-02 12:42       ` Srivatsa Vaddagiri
2007-04-02 14:16         ` Gautham R Shenoy
2007-04-02 18:56         ` Ingo Molnar
2007-04-03 12:56           ` Srivatsa Vaddagiri
2007-04-03 14:15             ` Gautham R Shenoy
2007-04-03 19:25               ` Rafael J. Wysocki
2007-04-04  3:15               ` Srivatsa Vaddagiri
2007-04-04 10:04                 ` Ingo Molnar
2007-04-04 10:41                   ` Gautham R Shenoy
2007-04-04 11:49                     ` Ingo Molnar
2007-04-04 12:24                       ` Gautham R Shenoy
2007-04-02 11:19   ` Gautham R Shenoy
2007-04-02 11:27     ` Ingo Molnar
2007-04-02 22:12       ` Rafael J. Wysocki
2007-04-02 13:22   ` Pavel Machek
2007-04-03 12:01   ` Gautham R Shenoy
2007-04-03 19:34     ` Rafael J. Wysocki
2007-04-03 20:24       ` Andrew Morton
2007-04-04 10:06         ` utrace merge Ingo Molnar
2007-04-04 10:36           ` Christoph Hellwig
2007-04-04 18:41             ` Andrew Morton
2007-04-03 14:01   ` [RFC] Cpu-hotplug: Using the Process Freezer (try2) Gautham R Shenoy

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=20070403135919.GB32444@in.ibm.com \
    --to=vatsa@in.ibm.com \
    --cc=akpm@linux-foundation.org \
    --cc=dino@in.ibm.com \
    --cc=dipankar@in.ibm.com \
    --cc=ego@in.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=masami.hiramatsu.pt@hitachi.com \
    --cc=mingo@elte.hu \
    --cc=oleg@tv-sign.ru \
    --cc=paulmck@us.ibm.com \
    --cc=rjw@sisk.pl \
    --cc=torvalds@linux-foundation.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.