Mistankingly did kref_get after kref_init From: dm-devel-bounces@xxxxxxxxxx [mailto:dm-devel-bounces@xxxxxxxxxx] On Behalf Of Hamburger, Menny 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 |
-- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel