[dm-devel] [PATCH] multipath: reference count on pgpath
Menny_Hamburger at Dell.com
Menny_Hamburger at Dell.com
Sun Jan 23 13:40:23 UTC 2011
Hi,
Here is the patch I am currently testing to solve the OOPs in pg_init_done (from send_mode_select).
The patch adds a reference count to pgpath, which ensures that activate_path has the pgpath intact when the call to scsi_dh_activate returns; thus any call to send_mode_select from within scsi_dh_rdac will call pg_init_done with a valid pgpath.
This patch is over RHEL5.4.
diff -r -U 2 a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
--- a/drivers/md/dm-mpath.c 2011-01-23 14:26:51.483249000 +0200
+++ b/drivers/md/dm-mpath.c 2011-01-23 14:26:51.521889000 +0200
@@ -21,4 +21,5 @@
#include <linux/time.h>
#include <linux/workqueue.h>
+#include <linux/kref.h>
#include <scsi/scsi_dh.h>
#include <asm/atomic.h>
@@ -34,4 +35,5 @@
struct priority_group *pg; /* Owning PG */
unsigned fail_count; /* Cumulative failure count */
+ struct kref ref_count;
struct path path;
@@ -129,4 +131,6 @@
memset(pgpath, 0, sizeof(*pgpath));
pgpath->path.is_active = 1;
+ kref_init(&pgpath->ref_count);
+ kref_get(&pgpath->ref_count);
INIT_WORK(&pgpath->activate_path, activate_path, pgpath);
}
@@ -140,4 +144,11 @@
}
+static void release_pgpath(struct kref *kref)
+{
+ struct pgpath *pgpath = container_of(kref, struct pgpath, ref_count);
+ free_pgpath(pgpath);
+
+}
+
static struct priority_group *alloc_priority_group(void)
{
@@ -164,5 +175,5 @@
scsi_dh_detach(bdev_get_queue(pgpath->path.dev->bdev));
dm_put_device(ti, pgpath->path.dev);
- free_pgpath(pgpath);
+ kref_put(&pgpath->ref_count, release_pgpath);
}
}
@@ -449,6 +460,8 @@
if (queue_delayed_work(kmpath_handlerd,
&tmp->activate_path, m->pg_init_delay ?
- m->pg_init_delay_secs * HZ : 0))
+ m->pg_init_delay_secs * HZ : 0)) {
+ kref_get(&pgpath->ref_count);
m->pg_init_in_progress++;
+ }
}
}
@@ -971,6 +984,8 @@
queue_work(kmultipathd, &m->process_queued_ios);
} else if (m->hw_handler_name && (m->current_pg == pgpath->pg)) {
- if (queue_work(kmpath_handlerd, &pgpath->activate_path))
+ if (queue_work(kmpath_handlerd, &pgpath->activate_path)) {
+ kref_get(&pgpath->ref_count);
m->pg_init_in_progress++;
+ }
}
@@ -1215,4 +1230,5 @@
scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev),
pg_init_done, &pgpath->path);
+ kref_put(&pgpath->ref_count, release_pgpath);
}
Menny Hamburger
Engineer
Dell | IDC
office +972 97698789, fax +972 97698889
Dell IDC. 4 Hacharoshet St, Raanana 43657, Israel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/dm-devel/attachments/20110123/4102bd2b/attachment.htm>
More information about the dm-devel
mailing list