From: Stefan Richter <stefanr@s5r6.in-berlin.de>
To: Tejun Heo <tj@kernel.org>
Cc: linux1394-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] firewire: sbp2: parallelize login/inquiry, reconnect, and shutdown
Date: Mon, 11 Oct 2010 23:27:42 +0200 (CEST) [thread overview]
Message-ID: <tkrat.1386de42b88d7218@s5r6.in-berlin.de> (raw)
In-Reply-To: <4CB3148C.5040902@kernel.org>
Tejun Heo wrote:
> On 10/10/2010 04:57 PM, Stefan Richter wrote:
> ...
>> Simply swap out the driver workqueue by system_nrt_wq. It provides all
>> the parallelism we will ever need, accepts long-running work, and
>> provides the here necessary guarantee of non-reentrance across all CPUs.
> ^^^^
> this probably should go away?
>
>> (The work items are scheduled from firewire-core's fw_device work items
>> which themselves may change CPUs.)
Yep.
[...]
>> --- a/drivers/firewire/sbp2.c
>> +++ b/drivers/firewire/sbp2.c
>> @@ -835,8 +835,6 @@ static void sbp2_target_put(struct sbp2_
>> kref_put(&tgt->kref, sbp2_release_target);
>> }
>>
>> -static struct workqueue_struct *sbp2_wq;
>> -
>> /*
>> * Always get the target's kref when scheduling work on one its units.
>> * Each workqueue job is responsible to call sbp2_target_put() upon return.
>> @@ -844,7 +842,7 @@ static struct workqueue_struct *sbp2_wq;
>> static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay)
>> {
>> sbp2_target_get(lu->tgt);
>> - if (!queue_delayed_work(sbp2_wq, &lu->work, delay))
>> + if (!queue_delayed_work(system_nrt_wq, &lu->work, delay))
>> sbp2_target_put(lu->tgt);
>> }
>>
>> @@ -1656,17 +1654,12 @@ MODULE_ALIAS("sbp2");
>>
>> static int __init sbp2_init(void)
>> {
>> - sbp2_wq = create_singlethread_workqueue(KBUILD_MODNAME);
>> - if (!sbp2_wq)
>> - return -ENOMEM;
>> -
>> return driver_register(&sbp2_driver.driver);
>> }
>>
>> static void __exit sbp2_cleanup(void)
>> {
>> driver_unregister(&sbp2_driver.driver);
>> - destroy_workqueue(sbp2_wq);
>
> Hmmm... from glancing the code, there doesn't seem to anything which
> can guarantee sbp2_release_target/reconnect() are finished before
> sbp2_cleanup() returns, so the code section might go away with code
> still running. It seems like the right thing to do here would be
> using alloc_workqueue(KBUILD_MODNAME, WQ_NON_REENTRANT, 0). Am I
> missing something?
There are indeed situations where the last module reference was already
put down before the work is run for the last time. Thanks for the hint.
What is preferable, an own workqueue instance whose destroy_workqueue()
lets sbp2_cleanup wait for unfinished work, or module ref-counting like
below?
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
[PATCH] firewire: sbp2: hold a reference for workqueue jobs
which can be run after sbp2_release. While SCSI core usually still
holds a reference to the firewire-sbp2 module at that point, it might
not do so anymore in some special cases where the scsi_device was
dropped earlier.
Reported-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
---
drivers/firewire/sbp2.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
Index: b/drivers/firewire/sbp2.c
===================================================================
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -821,8 +821,9 @@ static void sbp2_release_target(struct k
fw_notify("released %s, target %d:0:0\n", tgt->bus_id, shost->host_no);
fw_unit_put(tgt->unit);
- scsi_host_put(shost);
fw_device_put(device);
+ scsi_host_put(shost);
+ module_put(THIS_MODULE);
}
static void sbp2_target_get(struct sbp2_target *tgt)
@@ -1139,13 +1140,17 @@ static int sbp2_probe(struct device *dev
struct Scsi_Host *shost;
u32 model, firmware_revision;
+ /* Take a reference for late workqueue jobs. */
+ if (!try_module_get(THIS_MODULE))
+ return -ECANCELED;
+
if (dma_get_max_seg_size(device->card->device) > SBP2_MAX_SEG_SIZE)
BUG_ON(dma_set_max_seg_size(device->card->device,
SBP2_MAX_SEG_SIZE));
shost = scsi_host_alloc(&scsi_driver_template, sizeof(*tgt));
if (shost == NULL)
- return -ENOMEM;
+ goto fail;
tgt = (struct sbp2_target *)shost->hostdata;
dev_set_drvdata(&unit->device, tgt);
@@ -1200,6 +1205,8 @@ static int sbp2_probe(struct device *dev
fail_shost_put:
scsi_host_put(shost);
+ fail:
+ module_put(THIS_MODULE);
return -ENOMEM;
}
--
Stefan Richter
-=====-==-=- =-=- -=-==
http://arcgraph.de/sr/
next prev parent reply other threads:[~2010-10-11 21:27 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-10 14:55 [PATCH] firewire: core: use non-reentrant workqueue where necessary Stefan Richter
2010-10-10 14:57 ` [PATCH] firewire: sbp2: parallelize login/inquiry, reconnect, and shutdown Stefan Richter
2010-10-11 13:43 ` Tejun Heo
2010-10-11 21:27 ` Stefan Richter [this message]
2010-10-11 21:39 ` Stefan Richter
2010-10-12 13:55 ` Tejun Heo
2010-10-12 16:15 ` Stefan Richter
2010-10-12 16:46 ` Tejun Heo
2010-10-12 13:50 ` Tejun Heo
2010-10-12 21:39 ` [PATCH unfinished update] " Stefan Richter
2010-10-12 22:25 ` Stefan Richter
2010-10-12 23:09 ` Stefan Richter
2010-10-13 9:45 ` Tejun Heo
2010-10-11 13:29 ` [PATCH] firewire: core: use non-reentrant workqueue where necessary Tejun Heo
2010-10-11 19:05 ` Stefan Richter
2010-10-12 21:29 ` [PATCH update] firewire: core: use non-reentrant workqueue with rescuer Stefan Richter
2010-10-13 9:47 ` 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=tkrat.1386de42b88d7218@s5r6.in-berlin.de \
--to=stefanr@s5r6.in-berlin.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linux1394-devel@lists.sourceforge.net \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®