All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Hurley <peter@hurleysoftware.com>
To: Tejun Heo <tj@kernel.org>, laijs@cn.fujitsu.com
Cc: linux-kernel@vger.kernel.org,
	Stefan Richter <stefanr@s5r6.in-berlin.de>,
	linux1394-devel@lists.sourceforge.net,
	Chris Boot <bootc@bootc.net>,
	linux-scsi@vger.kernel.org, target-devel@vger.kernel.org
Subject: Re: [PATCH 4/9] firewire: don't use PREPARE_DELAYED_WORK
Date: Thu, 20 Feb 2014 20:44:46 -0500	[thread overview]
Message-ID: <5306AF8E.3080006@hurleysoftware.com> (raw)
In-Reply-To: <1392929071-16555-5-git-send-email-tj@kernel.org>

On 02/20/2014 03:44 PM, Tejun Heo wrote:
> PREPARE_[DELAYED_]WORK() are being phased out.  They have few users
> and a nasty surprise in terms of reentrancy guarantee as workqueue
> considers work items to be different if they don't have the same work
> function.
>
> firewire core-device and sbp2 have been been multiplexing work items
> with multiple work functions.  Introduce fw_device_workfn() and
> sbp2_lu_workfn() which invoke fw_device->workfn and
> sbp2_logical_unit->workfn respectively and always use the two
> functions as the work functions and update the users to set the
> ->workfn fields instead of overriding work functions using
> PREPARE_DELAYED_WORK().
>
> It would probably be best to route this with other related updates
> through the workqueue tree.
>
> Compile tested.
>
> Signed-off-by: Tejun Heo <tj@kernel.org>
> Cc: Stefan Richter <stefanr@s5r6.in-berlin.de>
> Cc: linux1394-devel@lists.sourceforge.net
> Cc: Chris Boot <bootc@bootc.net>
> Cc: linux-scsi@vger.kernel.org
> Cc: target-devel@vger.kernel.org
> ---
>   drivers/firewire/core-device.c | 22 +++++++++++++++-------
>   drivers/firewire/sbp2.c        | 17 +++++++++++++----
>   include/linux/firewire.h       |  1 +
>   3 files changed, 29 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c
> index de4aa40..2c6d5e1 100644
> --- a/drivers/firewire/core-device.c
> +++ b/drivers/firewire/core-device.c
> @@ -916,7 +916,7 @@ static int lookup_existing_device(struct device *dev, void *data)
>   		old->config_rom_retries = 0;
>   		fw_notice(card, "rediscovered device %s\n", dev_name(dev));
>
> -		PREPARE_DELAYED_WORK(&old->work, fw_device_update);
> +		old->workfn = fw_device_update;
>   		fw_schedule_device_work(old, 0);
>
>   		if (current_node == card->root_node)
> @@ -1075,7 +1075,7 @@ static void fw_device_init(struct work_struct *work)
>   	if (atomic_cmpxchg(&device->state,
>   			   FW_DEVICE_INITIALIZING,
>   			   FW_DEVICE_RUNNING) == FW_DEVICE_GONE) {
> -		PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
> +		device->workfn = fw_device_shutdown;
>   		fw_schedule_device_work(device, SHUTDOWN_DELAY);

Implied mb of test_and_set_bit() in queue_work_on() ensures that the
newly assigned work function is visible on all cpus before evaluating
whether or not the work can be queued.

Ok.

>   	} else {
>   		fw_notice(card, "created device %s: GUID %08x%08x, S%d00\n",
> @@ -1196,13 +1196,20 @@ static void fw_device_refresh(struct work_struct *work)
>   		  dev_name(&device->device), fw_rcode_string(ret));
>    gone:
>   	atomic_set(&device->state, FW_DEVICE_GONE);
> -	PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
> +	device->workfn = fw_device_shutdown;
>   	fw_schedule_device_work(device, SHUTDOWN_DELAY);
>    out:
>   	if (node_id == card->root_node->node_id)
>   		fw_schedule_bm_work(card, 0);
>   }
>
> +static void fw_device_workfn(struct work_struct *work)
> +{
> +	struct fw_device *device = container_of(to_delayed_work(work),
> +						struct fw_device, work);

I think this needs an smp_rmb() here.

> +	device->workfn(work);
> +}
> +

Otherwise this cpu could speculatively load workfn before
set_work_pool_and_clear_pending(), which means that the old workfn
could have been loaded but PENDING was still set and caused queue_work_on()
to reject the work as already pending.

Result: the new work function never runs.

But this exposes a more general problem that I believe workqueue should
prevent; speculated loads and stores in the work item function should be
prevented from occurring before clearing PENDING in
set_work_pool_and_clear_pending().

IOW, the beginning of the work function should act like a barrier in
the same way that queue_work_on() (et. al.) already does.

Regards,
Peter Hurley


  reply	other threads:[~2014-02-21  1:44 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-20 20:44 [PATCHSET wq/for-3.15] workqueue: remove PREPARE_[DELAYED_]WORK() Tejun Heo
2014-02-20 20:44 ` [PATCH 1/9] wireless/rt2x00: don't use PREPARE_WORK in rt2800usb.c Tejun Heo
2014-03-07 15:26   ` Tejun Heo
2014-02-20 20:44 ` [PATCH 2/9] ps3-vuart: don't use PREPARE_WORK Tejun Heo
2014-02-20 20:44   ` Tejun Heo
2014-02-21 23:19   ` Geoff Levand
2014-02-21 23:19     ` Geoff Levand
2014-02-20 20:44 ` [PATCH 3/9] floppy: don't use PREPARE_[DELAYED_]WORK Tejun Heo
2014-02-21  9:37   ` Jiri Kosina
2014-02-20 20:44 ` [PATCH 4/9] firewire: don't use PREPARE_DELAYED_WORK Tejun Heo
2014-02-20 20:44   ` Tejun Heo
2014-02-21  1:44   ` Peter Hurley [this message]
2014-02-21  1:59     ` Tejun Heo
2014-02-21  2:07       ` Peter Hurley
2014-02-21  2:07         ` Peter Hurley
2014-02-21  2:13         ` Tejun Heo
2014-02-21  5:13           ` Peter Hurley
2014-02-21 10:03             ` Tejun Heo
2014-02-21 12:51               ` Peter Hurley
2014-02-21 12:51                 ` Peter Hurley
2014-02-21 13:06                 ` Tejun Heo
2014-02-21 16:53                   ` Peter Hurley
2014-02-21 16:57                     ` Tejun Heo
2014-02-21 23:01                       ` Peter Hurley
2014-02-21 23:18                         ` Tejun Heo
2014-02-21 23:46                           ` Peter Hurley
2014-02-22 14:38                             ` Tejun Heo
2014-02-22 14:38                               ` Tejun Heo
2014-02-22 14:48                               ` Peter Hurley
2014-02-22 18:43                         ` James Bottomley
2014-02-22 18:48                           ` Peter Hurley
2014-02-22 18:48                             ` Peter Hurley
2014-02-22 18:52                             ` James Bottomley
2014-02-22 19:03                               ` Peter Hurley
2014-02-22 19:03                                 ` Peter Hurley
2014-02-23  1:23                                 ` memory-barriers.txt again (was Re: [PATCH 4/9] firewire: don't use PREPARE_DELAYED_WORK) Stefan Richter
2014-02-23 16:37                                   ` Paul E. McKenney
2014-02-23 16:37                                     ` Paul E. McKenney
2014-02-23 20:35                                     ` Peter Hurley
2014-02-23 23:50                                       ` Paul E. McKenney
2014-02-24  0:09                                         ` Peter Hurley
2014-02-24 16:26                                           ` Paul E. McKenney
2014-02-24 16:26                                             ` Paul E. McKenney
2014-02-24  0:32                                         ` Stefan Richter
2014-02-24 16:27                                           ` Paul E. McKenney
2014-02-23 20:05                                 ` [PATCH 4/9] firewire: don't use PREPARE_DELAYED_WORK James Bottomley
2014-02-23 22:32                                   ` Peter Hurley
2014-02-21 20:45   ` Stefan Richter
2014-02-21 20:45     ` Stefan Richter
2014-03-05 21:34     ` Stefan Richter
2014-03-07 15:18       ` Tejun Heo
2014-03-07 15:26   ` [PATCH UPDATED " Tejun Heo
2014-03-07 15:26     ` Tejun Heo
2014-02-20 20:44 ` [PATCH 5/9] usb: " Tejun Heo
2014-02-20 20:59   ` Greg Kroah-Hartman
2014-02-21 15:06     ` Alan Stern
2014-02-21 15:07       ` Tejun Heo
2014-02-22 14:59   ` [PATCH v2 " Tejun Heo
2014-02-22 15:14     ` Alan Stern
2014-02-22 15:20       ` Peter Hurley
2014-02-22 15:37       ` Tejun Heo
2014-02-22 23:03         ` Alan Stern
2014-02-23  4:29           ` Tejun Heo
2014-02-20 20:44 ` [PATCH 6/9] nvme: don't use PREPARE_WORK Tejun Heo
2014-02-20 20:44   ` Tejun Heo
2014-03-07 15:26   ` Tejun Heo
2014-03-07 15:26     ` Tejun Heo
2014-02-20 20:44 ` [PATCH 7/9] afs: " Tejun Heo
2014-03-07 15:27   ` Tejun Heo
2014-02-20 20:44 ` [PATCH 8/9] staging/fwserial: " Tejun Heo
2014-02-21 15:13   ` Peter Hurley
2014-02-20 20:44 ` [PATCH 9/9] workqueue: remove PREPARE_[DELAYED_]WORK() Tejun Heo
2014-03-07 15:27   ` Tejun Heo
2014-02-20 22:00 ` [PATCH 7/9] afs: don't use PREPARE_WORK David Howells
2014-02-20 22:46   ` Tejun Heo

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=5306AF8E.3080006@hurleysoftware.com \
    --to=peter@hurleysoftware.com \
    --cc=bootc@bootc.net \
    --cc=laijs@cn.fujitsu.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=linux1394-devel@lists.sourceforge.net \
    --cc=stefanr@s5r6.in-berlin.de \
    --cc=target-devel@vger.kernel.org \
    --cc=tj@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.