public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] sdd scsi-ml event wq
@ 2004-05-28  7:59 Mike Christie
  2004-05-28  8:15 ` Arjan van de Ven
  0 siblings, 1 reply; 7+ messages in thread
From: Mike Christie @ 2004-05-28  7:59 UTC (permalink / raw)
  To: SCSI Mailing List

[-- Attachment #1: Type: text/plain, Size: 311 bytes --]

The attached patch just adds a scsi-ml work queue to handle all
events. It also converts the transport_scsi_fc class to use it,
so drivers using that class do not have to worry about calling
the event functions from a process context.

The attached patch was built against my previous patch set.

Mike Christie

[-- Attachment #2: scsi-ml-event.patch --]
[-- Type: text/plain, Size: 6566 bytes --]

diff -Naurp linux-2.6.7-rc1/drivers/scsi/scsi.c linux-2.6.7-rc1-hotplug/drivers/scsi/scsi.c
--- linux-2.6.7-rc1/drivers/scsi/scsi.c	2004-05-27 00:36:22.000000000 -0700
+++ linux-2.6.7-rc1-hotplug/drivers/scsi/scsi.c	2004-05-27 20:46:30.000000000 -0700
@@ -1193,6 +1193,10 @@ static int __init init_scsi(void)
 	if (error)
 		goto cleanup_sysctl;
 
+	error = scsi_init_event_daemon();
+	if (error)
+		goto cleanup_sysfs;
+
 	for (i = 0; i < NR_CPUS; i++)
 		INIT_LIST_HEAD(&per_cpu(scsi_done_q, i));
 
@@ -1202,6 +1206,8 @@ static int __init init_scsi(void)
 	printk(KERN_NOTICE "SCSI subsystem initialized\n");
 	return 0;
 
+cleanup_sysfs:
+	scsi_sysfs_unregister();
 cleanup_sysctl:
 	scsi_exit_sysctl();
 cleanup_hosts:
@@ -1219,6 +1225,7 @@ cleanup_queue:
 
 static void __exit exit_scsi(void)
 {
+	scsi_shutdown_event_daemon();
 	scsi_sysfs_unregister();
 	scsi_exit_sysctl();
 	scsi_exit_hosts();
diff -Naurp linux-2.6.7-rc1/drivers/scsi/scsi_lib.c linux-2.6.7-rc1-hotplug/drivers/scsi/scsi_lib.c
--- linux-2.6.7-rc1/drivers/scsi/scsi_lib.c	2004-05-09 19:32:37.000000000 -0700
+++ linux-2.6.7-rc1-hotplug/drivers/scsi/scsi_lib.c	2004-05-27 23:53:36.000000000 -0700
@@ -15,9 +15,11 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/kobject.h>
 
 #include <scsi/scsi_driver.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_event.h>
 #include "scsi.h"
 
 #include "scsi_priv.h"
@@ -1691,3 +1693,88 @@ scsi_device_resume(struct scsi_device *s
 }
 EXPORT_SYMBOL(scsi_device_resume);
 
+static struct workqueue_struct *scsi_eventd;
+static kmem_cache_t *scsi_event_cache;
+static mempool_t *scsi_event_pool;
+#define EVENT_POOL_SIZE 64
+
+struct scsi_event {
+	struct work_struct work;
+	const char *action;
+	struct kobject *kobj;
+};
+
+int __init scsi_init_event_daemon(void)
+{
+	scsi_eventd = create_workqueue("scsi_event");
+	if (!scsi_eventd)
+		return -ENOMEM;
+
+	scsi_event_cache = kmem_cache_create("scsi_event",
+					     sizeof(struct scsi_event),
+					     0, 0, NULL, NULL);
+	if (!scsi_event_cache)
+		goto destroy_queue;
+
+	scsi_event_pool = mempool_create(EVENT_POOL_SIZE, mempool_alloc_slab,
+					 mempool_free_slab, scsi_event_cache);
+	if (scsi_event_pool)
+		return 0;
+
+	kmem_cache_destroy(scsi_event_cache);
+ destroy_queue:
+	destroy_workqueue(scsi_eventd);
+
+	return -ENOMEM;
+}
+
+void scsi_shutdown_event_daemon(void)
+{
+	mempool_destroy(scsi_event_pool);
+	kmem_cache_destroy(scsi_event_cache);
+	destroy_workqueue(scsi_eventd);
+}
+
+static void __scsi_hotplug_event(void *data)
+{
+	struct scsi_event *event = data;
+
+	kobject_hotplug(event->action, event->kobj);
+	kobject_put(event->kobj);
+	mempool_free(event, scsi_event_pool);
+}
+
+/**
+ *	scsi_hotplug_event - raises a userspace event.
+ *	@kobj: kobject from scsi data structure.
+ *	@action: the event type.
+ *
+ *	Sends an event through the kobject infrastructure.
+ *	returns 0 for success or an -Exxx value on error.
+ **/
+int scsi_hotplug_event(struct kobject *kobj, const char *action)
+{
+	struct scsi_event *event;
+
+	if (!kobj || !action)
+		return -EINVAL;
+
+	/* this handle is released in __scsi_hotplug_event */
+	if (!kobject_get(kobj))
+		return -EINVAL;
+
+	event = mempool_alloc(scsi_event_pool, GFP_ATOMIC);
+	if (!event) {
+		kobject_put(kobj);
+		return -ENOMEM;
+	}
+
+	event->kobj = kobj;
+	event->action = action;
+	INIT_WORK(&event->work, __scsi_hotplug_event, event);
+
+	queue_work(scsi_eventd, &event->work);
+
+	return 0;
+}
+EXPORT_SYMBOL(scsi_hotplug_event);
diff -Naurp linux-2.6.7-rc1/drivers/scsi/scsi_priv.h linux-2.6.7-rc1-hotplug/drivers/scsi/scsi_priv.h
--- linux-2.6.7-rc1/drivers/scsi/scsi_priv.h	2004-05-09 19:32:53.000000000 -0700
+++ linux-2.6.7-rc1-hotplug/drivers/scsi/scsi_priv.h	2004-05-27 21:09:48.000000000 -0700
@@ -116,6 +116,8 @@ extern struct request_queue *scsi_alloc_
 extern void scsi_free_queue(struct request_queue *q);
 extern int scsi_init_queue(void);
 extern void scsi_exit_queue(void);
+extern int scsi_init_event_daemon(void);
+extern void scsi_shutdown_event_daemon(void);
 
 /* scsi_proc.c */
 #ifdef CONFIG_SCSI_PROC_FS
diff -Naurp linux-2.6.7-rc1/drivers/scsi/scsi_transport_fc.c linux-2.6.7-rc1-hotplug/drivers/scsi/scsi_transport_fc.c
--- linux-2.6.7-rc1/drivers/scsi/scsi_transport_fc.c	2004-05-27 23:31:31.000000000 -0700
+++ linux-2.6.7-rc1-hotplug/drivers/scsi/scsi_transport_fc.c	2004-05-27 22:24:53.000000000 -0700
@@ -22,6 +22,7 @@
 #include <linux/kobject.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_event.h>
 #include <scsi/scsi_transport.h>
 #include <scsi/scsi_transport_fc.h>
 
@@ -77,28 +78,30 @@ static void __exit fc_transport_exit(voi
  *
  * Sends a hotplug event to userspace utilizing the
  * kobject infrastructure.
+ *
+ * returns 0 for success or an -Exxx value on error.
  */
-void fc_link_up(struct Scsi_Host *shost)
+int fc_link_up(struct Scsi_Host *shost)
 {
 	struct kobject *kobj;
 
 	if (!shost)
-		return;
+		return -EINVAL;
 
 	kobj = &shost->transport_classdev.kobj;
-	kobject_hotplug("fc_link_up", kobj);
+	return scsi_hotplug_event(kobj, "fc_link_up");
 }
 EXPORT_SYMBOL(fc_link_up);
 
-void fc_link_down(struct Scsi_Host *shost)
+int fc_link_down(struct Scsi_Host *shost)
 {
 	struct kobject *kobj;
 
 	if (!shost)
-		return;
+		return -EINVAL;
 
 	kobj = &shost->transport_classdev.kobj;
-	kobject_hotplug("fc_link_down", kobj);
+	return scsi_hotplug_event(kobj, "fc_link_down");
 }
 EXPORT_SYMBOL(fc_link_down);
 
diff -Naurp linux-2.6.7-rc1/include/scsi/scsi_event.h linux-2.6.7-rc1-hotplug/include/scsi/scsi_event.h
--- linux-2.6.7-rc1/include/scsi/scsi_event.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.7-rc1-hotplug/include/scsi/scsi_event.h	2004-05-27 23:53:19.000000000 -0700
@@ -0,0 +1,8 @@
+#ifndef _SCSI_SCSI_EVENT_H
+#define _SCSI_SCSI_EVENT_H
+
+#include <linux/kobject.h>
+
+int scsi_hotplug_event(struct kobject *, const char *);
+
+#endif
diff -Naurp linux-2.6.7-rc1/include/scsi/scsi_transport_fc.h linux-2.6.7-rc1-hotplug/include/scsi/scsi_transport_fc.h
--- linux-2.6.7-rc1/include/scsi/scsi_transport_fc.h	2004-05-09 19:32:27.000000000 -0700
+++ linux-2.6.7-rc1-hotplug/include/scsi/scsi_transport_fc.h	2004-05-27 22:02:35.000000000 -0700
@@ -52,5 +52,7 @@ struct fc_function_template {
 
 struct scsi_transport_template *fc_attach_transport(struct fc_function_template *);
 void fc_release_transport(struct scsi_transport_template *);
+int fc_link_up(struct Scsi_Host *);
+int fc_link_up(struct Scsi_Host *);
 
 #endif /* SCSI_TRANSPORT_FC_H */

^ permalink raw reply	[flat|nested] 7+ messages in thread
* Re: [PATCH] sdd scsi-ml event wq
@ 2004-06-03 10:46 Martin Peschke3
  0 siblings, 0 replies; 7+ messages in thread
From: Martin Peschke3 @ 2004-06-03 10:46 UTC (permalink / raw)
  To: Mike Christie; +Cc: Arjan van de Ven, SCSI Mailing List





> For the short term would it be best to harden the SCSI side of the API
then
> worry about the API we are using, or is the kobject_hotplug/userspace
route not
> looking to be the best option?

I am not sure for what other events this interface is going to be used.
However, for link down/up events there might be a feasible solution.
The minimum requirement is to ensure that paths are re-enabled on
link-up. If we use a flag in scsi_device for the link status, a flag in
scsi_device that indicates whether an event could be propagated,
and one spare buffer for an event then there should always be a way
to report a link-up event. If the spare buffer is being used when a
link-up event occurs, just set the scsi_device->linkup flag as well as
the scsi_device->lostevent flag and report the event later when the
spare buffer has been freed, provided that scsi_device->lostevent
was set. Which means that we might skip a few events in case of a
rapidly changing link status. But we would always report - with a minor
delay - the last, and therewith most important link event.

Martin


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2004-06-07  7:54 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-05-28  7:59 [PATCH] sdd scsi-ml event wq Mike Christie
2004-05-28  8:15 ` Arjan van de Ven
2004-05-28  9:07   ` Mike Christie
2004-05-28  9:18     ` Arjan van de Ven
2004-05-28 10:00       ` Mike Christie
2004-06-07  7:54         ` Douglas Gilbert
  -- strict thread matches above, loose matches on Subject: below --
2004-06-03 10:46 Martin Peschke3

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox