* [PATCH] add execute_in_process_context() API
@ 2006-02-07 20:00 James Bottomley
2006-02-07 20:08 ` [SCSI] fix wrong context bugs in SCSI James Bottomley
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: James Bottomley @ 2006-02-07 20:00 UTC (permalink / raw)
To: linux-kernel, linux-scsi, Andrew Morton
SCSI needs this for our scheme to avoid executing generic device release
calls from interrupt context (SCSI patch using this to follow).
If no-one objects, I'd like to slide this into the scsi-rc-fixes-2.6
tree for 2.6.16.
James
--
[PATCH] add execute_in_process_context() API
We have several points in the SCSI stack (primarily for our device
functions) where we need to guarantee process context, but (given the
place where the last reference was released) we cannot guarantee this.
This API gets around the issue by executing the function directly if
the caller has process context, but scheduling a workqueue to execute
in process context if the caller doesn't have it.
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Index: BUILD-2.6/include/linux/workqueue.h
===================================================================
--- BUILD-2.6.orig/include/linux/workqueue.h 2006-02-07 09:22:30.000000000 -0600
+++ BUILD-2.6/include/linux/workqueue.h 2006-02-07 10:22:29.000000000 -0600
@@ -74,6 +74,7 @@
void cancel_rearming_delayed_work(struct work_struct *work);
void cancel_rearming_delayed_workqueue(struct workqueue_struct *,
struct work_struct *);
+int execute_in_process_context(void (*fn)(void *), void *);
/*
* Kill off a pending schedule_delayed_work(). Note that the work callback
Index: BUILD-2.6/kernel/workqueue.c
===================================================================
--- BUILD-2.6.orig/kernel/workqueue.c 2006-02-07 09:22:30.000000000 -0600
+++ BUILD-2.6/kernel/workqueue.c 2006-02-07 11:07:47.000000000 -0600
@@ -27,6 +27,7 @@
#include <linux/cpu.h>
#include <linux/notifier.h>
#include <linux/kthread.h>
+#include <linux/hardirq.h>
/*
* The per-CPU workqueue (if single thread, we always use the first
@@ -476,6 +477,63 @@
}
EXPORT_SYMBOL(cancel_rearming_delayed_work);
+struct work_queue_work {
+ struct work_struct work;
+ void (*fn)(void *);
+ void *data;
+};
+
+static void execute_in_process_context_work(void *data)
+{
+ void (*fn)(void *data);
+ struct work_queue_work *wqw = data;
+
+ fn = wqw->fn;
+ data = wqw->data;
+
+ kfree(wqw);
+
+ fn(data);
+}
+
+/**
+ * execute_in_process_context - reliably execute the routine with user context
+ * @fn: the function to execute
+ * @data: data to pass to the function
+ *
+ * Executes the function immediately if process context is available,
+ * otherwise schedules the function for delayed execution.
+ *
+ * Returns: 0 - function was executed
+ * 1 - function was scheduled for execution
+ * <0 - error
+ */
+int execute_in_process_context(void (*fn)(void *data), void *data)
+{
+ struct work_queue_work *wqw;
+
+ if (!in_interrupt()) {
+ fn(data);
+ return 0;
+ }
+
+ wqw = kmalloc(sizeof(struct work_queue_work), GFP_ATOMIC);
+
+ if (unlikely(!wqw)) {
+ printk(KERN_ERR "Failed to allocate memory\n");
+ WARN_ON(1);
+ return -ENOMEM;
+ }
+
+ INIT_WORK(&wqw->work, execute_in_process_context_work, wqw);
+ wqw->fn = fn;
+ wqw->data = data;
+ schedule_work(&wqw->work);
+
+ return 1;
+}
+EXPORT_SYMBOL_GPL(execute_in_process_context);
+
int keventd_up(void)
{
return keventd_wq != NULL;
^ permalink raw reply [flat|nested] 12+ messages in thread* [SCSI] fix wrong context bugs in SCSI
2006-02-07 20:00 [PATCH] add execute_in_process_context() API James Bottomley
@ 2006-02-07 20:08 ` James Bottomley
2006-02-07 22:05 ` Brian King
2006-02-08 8:56 ` Jens Axboe
2006-02-07 20:26 ` [PATCH] add execute_in_process_context() API Dave Jones
2006-02-08 12:51 ` Stefan Richter
2 siblings, 2 replies; 12+ messages in thread
From: James Bottomley @ 2006-02-07 20:08 UTC (permalink / raw)
To: linux-kernel; +Cc: linux-scsi, Andrew Morton
This is the second half of the execute_process_context() API addition:
an actual user
James
--
[SCSI] fix wrong context bugs in SCSI
There's a bug in releasing scsi_device where the release function
actually frees the block queue. However, the block queue release
calls flush_work(), which requires process context (the scsi_device
structure may release from irq context). Update the release function
to invoke via the execute_in_process_context() API.
Also clean up the scsi_target structure releasing via this API.
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Index: BUILD-2.6/drivers/scsi/scsi_scan.c
===================================================================
--- BUILD-2.6.orig/drivers/scsi/scsi_scan.c 2006-02-07 09:23:44.000000000 -0600
+++ BUILD-2.6/drivers/scsi/scsi_scan.c 2006-02-07 11:35:46.000000000 -0600
@@ -385,19 +385,12 @@
return found_target;
}
-struct work_queue_wrapper {
- struct work_struct work;
- struct scsi_target *starget;
-};
-
-static void scsi_target_reap_work(void *data) {
- struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data;
- struct scsi_target *starget = wqw->starget;
+static void scsi_target_reap_usercontext(void *data)
+{
+ struct scsi_target *starget = data;
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
unsigned long flags;
- kfree(wqw);
-
spin_lock_irqsave(shost->host_lock, flags);
if (--starget->reap_ref == 0 && list_empty(&starget->devices)) {
@@ -426,18 +419,7 @@
*/
void scsi_target_reap(struct scsi_target *starget)
{
- struct work_queue_wrapper *wqw =
- kzalloc(sizeof(struct work_queue_wrapper), GFP_ATOMIC);
-
- if (!wqw) {
- starget_printk(KERN_ERR, starget,
- "Failed to allocate memory in scsi_reap_target()\n");
- return;
- }
-
- INIT_WORK(&wqw->work, scsi_target_reap_work, wqw);
- wqw->starget = starget;
- schedule_work(&wqw->work);
+ execute_in_process_context(scsi_target_reap_usercontext, starget);
}
/**
Index: BUILD-2.6/drivers/scsi/scsi_sysfs.c
===================================================================
--- BUILD-2.6.orig/drivers/scsi/scsi_sysfs.c 2006-02-07 09:23:44.000000000 -0600
+++ BUILD-2.6/drivers/scsi/scsi_sysfs.c 2006-02-07 11:35:08.000000000 -0600
@@ -217,8 +217,9 @@
put_device(&sdev->sdev_gendev);
}
-static void scsi_device_dev_release(struct device *dev)
+static void scsi_device_dev_release_usercontext(void *data)
{
+ struct device *dev = data;
struct scsi_device *sdev;
struct device *parent;
struct scsi_target *starget;
@@ -237,6 +238,7 @@
if (sdev->request_queue) {
sdev->request_queue->queuedata = NULL;
+ /* user context needed to free queue */
scsi_free_queue(sdev->request_queue);
/* temporary expedient, try to catch use of queue lock
* after free of sdev */
@@ -252,6 +254,11 @@
put_device(parent);
}
+static void scsi_device_dev_release(struct device *dev)
+{
+ execute_in_process_context(scsi_device_dev_release_usercontext, dev);
+}
+
static struct class sdev_class = {
.name = "scsi_device",
.release = scsi_device_cls_release,
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [SCSI] fix wrong context bugs in SCSI
2006-02-07 20:08 ` [SCSI] fix wrong context bugs in SCSI James Bottomley
@ 2006-02-07 22:05 ` Brian King
2006-02-07 23:26 ` James Bottomley
2006-02-08 8:56 ` Jens Axboe
1 sibling, 1 reply; 12+ messages in thread
From: Brian King @ 2006-02-07 22:05 UTC (permalink / raw)
To: James Bottomley; +Cc: linux-kernel, linux-scsi, Andrew Morton
James Bottomley wrote:
> This is the second half of the execute_process_context() API addition:
> an actual user
I just tried this out on my ppc64 box. I recently noticed that
the target reaping via workqueue change that went in not too long ago
resulted in *really* slow user initiated wildcard scans for ipr
adapters - in the neighborhood of 6 minutes... Your patch brings
that back down to 8 seconds.
Brian
>
> James
>
> --
>
> [SCSI] fix wrong context bugs in SCSI
>
> There's a bug in releasing scsi_device where the release function
> actually frees the block queue. However, the block queue release
> calls flush_work(), which requires process context (the scsi_device
> structure may release from irq context). Update the release function
> to invoke via the execute_in_process_context() API.
>
> Also clean up the scsi_target structure releasing via this API.
>
> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
>
> Index: BUILD-2.6/drivers/scsi/scsi_scan.c
> ===================================================================
> --- BUILD-2.6.orig/drivers/scsi/scsi_scan.c 2006-02-07 09:23:44.000000000 -0600
> +++ BUILD-2.6/drivers/scsi/scsi_scan.c 2006-02-07 11:35:46.000000000 -0600
> @@ -385,19 +385,12 @@
> return found_target;
> }
>
> -struct work_queue_wrapper {
> - struct work_struct work;
> - struct scsi_target *starget;
> -};
> -
> -static void scsi_target_reap_work(void *data) {
> - struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data;
> - struct scsi_target *starget = wqw->starget;
> +static void scsi_target_reap_usercontext(void *data)
> +{
> + struct scsi_target *starget = data;
> struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
> unsigned long flags;
>
> - kfree(wqw);
> -
> spin_lock_irqsave(shost->host_lock, flags);
>
> if (--starget->reap_ref == 0 && list_empty(&starget->devices)) {
> @@ -426,18 +419,7 @@
> */
> void scsi_target_reap(struct scsi_target *starget)
> {
> - struct work_queue_wrapper *wqw =
> - kzalloc(sizeof(struct work_queue_wrapper), GFP_ATOMIC);
> -
> - if (!wqw) {
> - starget_printk(KERN_ERR, starget,
> - "Failed to allocate memory in scsi_reap_target()\n");
> - return;
> - }
> -
> - INIT_WORK(&wqw->work, scsi_target_reap_work, wqw);
> - wqw->starget = starget;
> - schedule_work(&wqw->work);
> + execute_in_process_context(scsi_target_reap_usercontext, starget);
> }
>
> /**
> Index: BUILD-2.6/drivers/scsi/scsi_sysfs.c
> ===================================================================
> --- BUILD-2.6.orig/drivers/scsi/scsi_sysfs.c 2006-02-07 09:23:44.000000000 -0600
> +++ BUILD-2.6/drivers/scsi/scsi_sysfs.c 2006-02-07 11:35:08.000000000 -0600
> @@ -217,8 +217,9 @@
> put_device(&sdev->sdev_gendev);
> }
>
> -static void scsi_device_dev_release(struct device *dev)
> +static void scsi_device_dev_release_usercontext(void *data)
> {
> + struct device *dev = data;
> struct scsi_device *sdev;
> struct device *parent;
> struct scsi_target *starget;
> @@ -237,6 +238,7 @@
>
> if (sdev->request_queue) {
> sdev->request_queue->queuedata = NULL;
> + /* user context needed to free queue */
> scsi_free_queue(sdev->request_queue);
> /* temporary expedient, try to catch use of queue lock
> * after free of sdev */
> @@ -252,6 +254,11 @@
> put_device(parent);
> }
>
> +static void scsi_device_dev_release(struct device *dev)
> +{
> + execute_in_process_context(scsi_device_dev_release_usercontext, dev);
> +}
> +
> static struct class sdev_class = {
> .name = "scsi_device",
> .release = scsi_device_cls_release,
>
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
Brian King
eServer Storage I/O
IBM Linux Technology Center
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [SCSI] fix wrong context bugs in SCSI
2006-02-07 22:05 ` Brian King
@ 2006-02-07 23:26 ` James Bottomley
0 siblings, 0 replies; 12+ messages in thread
From: James Bottomley @ 2006-02-07 23:26 UTC (permalink / raw)
To: brking; +Cc: linux-kernel, linux-scsi, Andrew Morton
On Tue, 2006-02-07 at 16:05 -0600, Brian King wrote:
> I just tried this out on my ppc64 box. I recently noticed that
> the target reaping via workqueue change that went in not too long ago
> resulted in *really* slow user initiated wildcard scans for ipr
> adapters - in the neighborhood of 6 minutes... Your patch brings
> that back down to 8 seconds.
Yes, that's because the original fix used a workqueue for everything
(whether it needed it or not). The new API checks the context first
before invoking a workqueue. By and large, for SCSI, we actually have
user context most of the time, so the old fix was rather heavy handed.
James
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [SCSI] fix wrong context bugs in SCSI
2006-02-07 20:08 ` [SCSI] fix wrong context bugs in SCSI James Bottomley
2006-02-07 22:05 ` Brian King
@ 2006-02-08 8:56 ` Jens Axboe
2006-02-08 15:31 ` James Bottomley
1 sibling, 1 reply; 12+ messages in thread
From: Jens Axboe @ 2006-02-08 8:56 UTC (permalink / raw)
To: James Bottomley; +Cc: linux-kernel, linux-scsi, Andrew Morton
On Tue, Feb 07 2006, James Bottomley wrote:
> +static void scsi_device_dev_release(struct device *dev)
> +{
> + execute_in_process_context(scsi_device_dev_release_usercontext, dev);
> +}
> +
Hmm, this (and further up) could fail, yet you don't check.
I don't think this API is very nice to be honest, there's no good way to
handle failures - you can't just sleep and loop retry the execute if you
are in_interrupt(). I'd prefer passing in a work_queue_work (with a
better name :-) that has been allocated at a reliable time during
initialization.
--
Jens Axboe
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [SCSI] fix wrong context bugs in SCSI
2006-02-08 8:56 ` Jens Axboe
@ 2006-02-08 15:31 ` James Bottomley
2006-02-08 15:52 ` Jens Axboe
0 siblings, 1 reply; 12+ messages in thread
From: James Bottomley @ 2006-02-08 15:31 UTC (permalink / raw)
To: Jens Axboe; +Cc: linux-kernel, linux-scsi, Andrew Morton
On Wed, 2006-02-08 at 09:56 +0100, Jens Axboe wrote:
> Hmm, this (and further up) could fail, yet you don't check.
By and large, you have process context, so this isn't going to be a
problem.
> I don't think this API is very nice to be honest, there's no good way to
> handle failures - you can't just sleep and loop retry the execute if you
> are in_interrupt(). I'd prefer passing in a work_queue_work (with a
> better name :-) that has been allocated at a reliable time during
> initialization.
Yes, I agree ... however, the failure is less prevalent in the new code
than the old. The problem is that we may need to execute multiple puts
for a single target from irq contex, so under this scheme you need a wqw
(potentially) for every get.
I could solve this by binding the API more tightly into the device
model, so the generic device contains the wqw and it is told that the
release function of the final put must be called in process context, but
that's an awful lot of code changes.
James
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [SCSI] fix wrong context bugs in SCSI
2006-02-08 15:31 ` James Bottomley
@ 2006-02-08 15:52 ` Jens Axboe
2006-02-14 16:42 ` James Bottomley
0 siblings, 1 reply; 12+ messages in thread
From: Jens Axboe @ 2006-02-08 15:52 UTC (permalink / raw)
To: James Bottomley; +Cc: linux-kernel, linux-scsi, Andrew Morton
On Wed, Feb 08 2006, James Bottomley wrote:
> On Wed, 2006-02-08 at 09:56 +0100, Jens Axboe wrote:
> > Hmm, this (and further up) could fail, yet you don't check.
>
> By and large, you have process context, so this isn't going to be a
> problem.
>
> > I don't think this API is very nice to be honest, there's no good way to
> > handle failures - you can't just sleep and loop retry the execute if you
> > are in_interrupt(). I'd prefer passing in a work_queue_work (with a
> > better name :-) that has been allocated at a reliable time during
> > initialization.
>
> Yes, I agree ... however, the failure is less prevalent in the new code
> than the old. The problem is that we may need to execute multiple puts
> for a single target from irq contex, so under this scheme you need a wqw
> (potentially) for every get.
>
> I could solve this by binding the API more tightly into the device
> model, so the generic device contains the wqw and it is told that the
> release function of the final put must be called in process context, but
> that's an awful lot of code changes.
Yeah it does get a lot more complicated. I guess I'm fine with the
current change, but please just keep it in SCSI then. It's not the sort
of thing you'd want to advertise as an exported API.
--
Jens Axboe
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [SCSI] fix wrong context bugs in SCSI
2006-02-08 15:52 ` Jens Axboe
@ 2006-02-14 16:42 ` James Bottomley
2006-02-14 16:48 ` James Bottomley
0 siblings, 1 reply; 12+ messages in thread
From: James Bottomley @ 2006-02-14 16:42 UTC (permalink / raw)
To: Jens Axboe; +Cc: linux-kernel, linux-scsi, Andrew Morton
On Wed, 2006-02-08 at 16:52 +0100, Jens Axboe wrote:
> Yeah it does get a lot more complicated. I guess I'm fine with the
> current change, but please just keep it in SCSI then. It's not the sort
> of thing you'd want to advertise as an exported API.
OK, this pulls the API into scsi for 2.6.16
James
---
[PATCH] add scsi_execute_in_process_context() API
We have several points in the SCSI stack (primarily for our device
functions) where we need to guarantee process context, but (given the
place where the last reference was released) we cannot guarantee this.
This API gets around the issue by executing the function directly if
the caller has process context, but scheduling a workqueue to execute
in process context if the caller doesn't have it. Unfortunately, it
requires memory allocation in interrupt context, but it's better than
what we have previously. The true solution will require a bit of
re-engineering, so isn't appropriate for 2.6.16.
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Index: BUILD-2.6/drivers/scsi/scsi_lib.c
===================================================================
--- BUILD-2.6.orig/drivers/scsi/scsi_lib.c 2006-02-12 12:37:18.000000000 -0600
+++ BUILD-2.6/drivers/scsi/scsi_lib.c 2006-02-14 10:17:12.000000000 -0600
@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/delay.h>
+#include <linux/hardirq.h>
#include <scsi/scsi.h>
#include <scsi/scsi_dbg.h>
@@ -2248,3 +2249,61 @@
device_for_each_child(dev, NULL, target_unblock);
}
EXPORT_SYMBOL_GPL(scsi_target_unblock);
+
+
+struct work_queue_work {
+ struct work_struct work;
+ void (*fn)(void *);
+ void *data;
+};
+
+static void execute_in_process_context_work(void *data)
+{
+ void (*fn)(void *data);
+ struct work_queue_work *wqw = data;
+
+ fn = wqw->fn;
+ data = wqw->data;
+
+ kfree(wqw);
+
+ fn(data);
+}
+
+/**
+ * scsi_execute_in_process_context - reliably execute the routine with user context
+ * @fn: the function to execute
+ * @data: data to pass to the function
+ *
+ * Executes the function immediately if process context is available,
+ * otherwise schedules the function for delayed execution.
+ *
+ * Returns: 0 - function was executed
+ * 1 - function was scheduled for execution
+ * <0 - error
+ */
+int scsi_execute_in_process_context(void (*fn)(void *data), void *data)
+{
+ struct work_queue_work *wqw;
+
+ if (!in_interrupt()) {
+ fn(data);
+ return 0;
+ }
+
+ wqw = kmalloc(sizeof(struct work_queue_work), GFP_ATOMIC);
+
+ if (unlikely(!wqw)) {
+ printk(KERN_ERR "Failed to allocate memory\n");
+ WARN_ON(1);
+ return -ENOMEM;
+ }
+
+ INIT_WORK(&wqw->work, execute_in_process_context_work, wqw);
+ wqw->fn = fn;
+ wqw->data = data;
+ schedule_work(&wqw->work);
+
+ return 1;
+}
+EXPORT_SYMBOL_GPL(scsi_execute_in_process_context);
Index: BUILD-2.6/include/scsi/scsi.h
===================================================================
--- BUILD-2.6.orig/include/scsi/scsi.h 2006-02-12 12:38:10.000000000 -0600
+++ BUILD-2.6/include/scsi/scsi.h 2006-02-14 09:07:54.000000000 -0600
@@ -433,4 +433,6 @@
/* Used to obtain the PCI location of a device */
#define SCSI_IOCTL_GET_PCI 0x5387
+int scsi_execute_in_process_context(void (*fn)(void *data), void *data);
+
#endif /* _SCSI_SCSI_H */
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [SCSI] fix wrong context bugs in SCSI
2006-02-14 16:42 ` James Bottomley
@ 2006-02-14 16:48 ` James Bottomley
0 siblings, 0 replies; 12+ messages in thread
From: James Bottomley @ 2006-02-14 16:48 UTC (permalink / raw)
To: Jens Axboe; +Cc: linux-kernel, linux-scsi, Andrew Morton
And the second part
James
---
[SCSI] fix wrong context bugs in SCSI
There's a bug in releasing scsi_device where the release function
actually frees the block queue. However, the block queue release
calls flush_work(), which requires process context (the scsi_device
structure may release from irq context). Update the release function
to invoke via the execute_in_process_context() API.
Also clean up the scsi_target structure releasing via this API.
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Index: BUILD-2.6/drivers/scsi/scsi_scan.c
===================================================================
--- BUILD-2.6.orig/drivers/scsi/scsi_scan.c 2006-02-12 12:37:18.000000000 -0600
+++ BUILD-2.6/drivers/scsi/scsi_scan.c 2006-02-14 09:08:43.000000000 -0600
@@ -387,19 +387,12 @@
return found_target;
}
-struct work_queue_wrapper {
- struct work_struct work;
- struct scsi_target *starget;
-};
-
-static void scsi_target_reap_work(void *data) {
- struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data;
- struct scsi_target *starget = wqw->starget;
+static void scsi_target_reap_usercontext(void *data)
+{
+ struct scsi_target *starget = data;
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
unsigned long flags;
- kfree(wqw);
-
spin_lock_irqsave(shost->host_lock, flags);
if (--starget->reap_ref == 0 && list_empty(&starget->devices)) {
@@ -428,18 +421,7 @@
*/
void scsi_target_reap(struct scsi_target *starget)
{
- struct work_queue_wrapper *wqw =
- kzalloc(sizeof(struct work_queue_wrapper), GFP_ATOMIC);
-
- if (!wqw) {
- starget_printk(KERN_ERR, starget,
- "Failed to allocate memory in scsi_reap_target()\n");
- return;
- }
-
- INIT_WORK(&wqw->work, scsi_target_reap_work, wqw);
- wqw->starget = starget;
- schedule_work(&wqw->work);
+ scsi_execute_in_process_context(scsi_target_reap_usercontext, starget);
}
/**
Index: BUILD-2.6/drivers/scsi/scsi_sysfs.c
===================================================================
--- BUILD-2.6.orig/drivers/scsi/scsi_sysfs.c 2006-02-12 12:37:18.000000000 -0600
+++ BUILD-2.6/drivers/scsi/scsi_sysfs.c 2006-02-14 09:08:52.000000000 -0600
@@ -217,8 +217,9 @@
put_device(&sdev->sdev_gendev);
}
-static void scsi_device_dev_release(struct device *dev)
+static void scsi_device_dev_release_usercontext(void *data)
{
+ struct device *dev = data;
struct scsi_device *sdev;
struct device *parent;
struct scsi_target *starget;
@@ -237,6 +238,7 @@
if (sdev->request_queue) {
sdev->request_queue->queuedata = NULL;
+ /* user context needed to free queue */
scsi_free_queue(sdev->request_queue);
/* temporary expedient, try to catch use of queue lock
* after free of sdev */
@@ -252,6 +254,11 @@
put_device(parent);
}
+static void scsi_device_dev_release(struct device *dev)
+{
+ scsi_execute_in_process_context(scsi_device_dev_release_usercontext, dev);
+}
+
static struct class sdev_class = {
.name = "scsi_device",
.release = scsi_device_cls_release,
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] add execute_in_process_context() API
2006-02-07 20:00 [PATCH] add execute_in_process_context() API James Bottomley
2006-02-07 20:08 ` [SCSI] fix wrong context bugs in SCSI James Bottomley
@ 2006-02-07 20:26 ` Dave Jones
2006-02-07 20:34 ` Andrew Morton
2006-02-08 12:51 ` Stefan Richter
2 siblings, 1 reply; 12+ messages in thread
From: Dave Jones @ 2006-02-07 20:26 UTC (permalink / raw)
To: James Bottomley; +Cc: linux-kernel, linux-scsi, Andrew Morton
On Tue, Feb 07, 2006 at 02:00:19PM -0600, James Bottomley wrote:
> +int execute_in_process_context(void (*fn)(void *data), void *data)
> +{
> + struct work_queue_work *wqw;
> +
> + if (!in_interrupt()) {
> + fn(data);
> + return 0;
> + }
> +
> + wqw = kmalloc(sizeof(struct work_queue_work), GFP_ATOMIC);
> +
> + if (unlikely(!wqw)) {
> + printk(KERN_ERR "Failed to allocate memory\n");
> + WARN_ON(1);
> + return -ENOMEM;
> + }
> +
> + INIT_WORK(&wqw->work, execute_in_process_context_work, wqw);
> + wqw->fn = fn;
> + wqw->data = data;
> + schedule_work(&wqw->work);
> +
> + return 1;
> +}
After the workqueue has run, what free's wqw ?
Dave
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH] add execute_in_process_context() API
2006-02-07 20:26 ` [PATCH] add execute_in_process_context() API Dave Jones
@ 2006-02-07 20:34 ` Andrew Morton
0 siblings, 0 replies; 12+ messages in thread
From: Andrew Morton @ 2006-02-07 20:34 UTC (permalink / raw)
To: Dave Jones; +Cc: James.Bottomley, linux-kernel, linux-scsi
Dave Jones <davej@redhat.com> wrote:
>
> On Tue, Feb 07, 2006 at 02:00:19PM -0600, James Bottomley wrote:
> > +int execute_in_process_context(void (*fn)(void *data), void *data)
> > +{
> > + struct work_queue_work *wqw;
> > +
> > + if (!in_interrupt()) {
> > + fn(data);
> > + return 0;
> > + }
> > +
> > + wqw = kmalloc(sizeof(struct work_queue_work), GFP_ATOMIC);
> > +
> > + if (unlikely(!wqw)) {
> > + printk(KERN_ERR "Failed to allocate memory\n");
> > + WARN_ON(1);
> > + return -ENOMEM;
> > + }
> > +
> > + INIT_WORK(&wqw->work, execute_in_process_context_work, wqw);
> > + wqw->fn = fn;
> > + wqw->data = data;
> > + schedule_work(&wqw->work);
> > +
> > + return 1;
> > +}
>
> After the workqueue has run, what free's wqw ?
>
The callback (execute_in_process_context_work())
The trap with this patch is that the caller has to run
flush_scheduled_work() at the right time. But hopefully anyone who's using
it knows that by now.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] add execute_in_process_context() API
2006-02-07 20:00 [PATCH] add execute_in_process_context() API James Bottomley
2006-02-07 20:08 ` [SCSI] fix wrong context bugs in SCSI James Bottomley
2006-02-07 20:26 ` [PATCH] add execute_in_process_context() API Dave Jones
@ 2006-02-08 12:51 ` Stefan Richter
2 siblings, 0 replies; 12+ messages in thread
From: Stefan Richter @ 2006-02-08 12:51 UTC (permalink / raw)
To: James Bottomley; +Cc: linux-kernel, linux-scsi, Andrew Morton
James Bottomley wrote:
> SCSI needs this for our scheme to avoid executing generic device release
> calls from interrupt context (SCSI patch using this to follow).
Shouldn't we rather fix the SCSI low level drivers or SCSI transport
layers to trigger device releases only from process context? (Instead of
SCSI core transparently falling back to a workqueue, that is.)
I know only one of these drivers, hence I don't know which are actually
affected and how much work that would be.
--
Stefan Richter
-=====-=-==- --=- -=---
http://arcgraph.de/sr/
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2006-02-14 16:48 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-02-07 20:00 [PATCH] add execute_in_process_context() API James Bottomley
2006-02-07 20:08 ` [SCSI] fix wrong context bugs in SCSI James Bottomley
2006-02-07 22:05 ` Brian King
2006-02-07 23:26 ` James Bottomley
2006-02-08 8:56 ` Jens Axboe
2006-02-08 15:31 ` James Bottomley
2006-02-08 15:52 ` Jens Axboe
2006-02-14 16:42 ` James Bottomley
2006-02-14 16:48 ` James Bottomley
2006-02-07 20:26 ` [PATCH] add execute_in_process_context() API Dave Jones
2006-02-07 20:34 ` Andrew Morton
2006-02-08 12:51 ` Stefan Richter
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).