From mboxrd@z Thu Jan 1 00:00:00 1970 From: James Bottomley Subject: Re: Fw: crash on x86_64 - mm related? Date: Thu, 15 Dec 2005 20:01:43 -0800 Message-ID: <1134705703.3906.1.camel@mulgrave> References: <20051206160815.GC11560@tau.solarneutrino.net> <20051206204336.GA12248@tau.solarneutrino.net> <20051212165443.GD17295@tau.solarneutrino.net> <1134409531.9994.13.camel@mulgrave> <1134411882.9994.18.camel@mulgrave> <20051215190930.GA20156@tau.solarneutrino.net> Mime-Version: 1.0 Content-Type: text/plain Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <20051215190930.GA20156@tau.solarneutrino.net> Sender: linux-kernel-owner@vger.kernel.org To: Ryan Richter Cc: Linus Torvalds , Hugh Dickins , Kai Makisara , Andrew Morton , linux-kernel@vger.kernel.org, linux-scsi@vger.kernel.org List-Id: linux-scsi@vger.kernel.org On Thu, 2005-12-15 at 14:09 -0500, Ryan Richter wrote: > On Mon, Dec 12, 2005 at 12:24:42PM -0600, James Bottomley wrote: > > I'll find a fix for the real problem, but this patch isn't the cause. > > Is the patch set you posted yesterday supposed to fix this? If so, is > it available in patch form anywhere? No, I've been too busin integrating other people's patches to work on ones of my own. Try this. James diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -400,6 +400,35 @@ static struct scsi_target *scsi_alloc_ta 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; + 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)) { + list_del_init(&starget->siblings); + spin_unlock_irqrestore(shost->host_lock, flags); + device_del(&starget->dev); + transport_unregister_device(&starget->dev); + put_device(&starget->dev); + return; + + } + spin_unlock_irqrestore(shost->host_lock, flags); + + return; +} + /** * scsi_target_reap - check to see if target is in use and destroy if not * @@ -411,19 +440,18 @@ static struct scsi_target *scsi_alloc_ta */ void scsi_target_reap(struct scsi_target *starget) { - struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); - unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + struct work_queue_wrapper *wqw = + kzalloc(sizeof(struct work_queue_wrapper), GFP_ATOMIC); - if (--starget->reap_ref == 0 && list_empty(&starget->devices)) { - list_del_init(&starget->siblings); - spin_unlock_irqrestore(shost->host_lock, flags); - device_del(&starget->dev); - transport_unregister_device(&starget->dev); - put_device(&starget->dev); + if (!wqw) { + starget_printk(KERN_ERR, starget, + "Failed to allocate memory in scsi_reap_target()\n"); return; } - spin_unlock_irqrestore(shost->host_lock, flags); + + INIT_WORK(&wqw->work, scsi_target_reap_work, wqw); + wqw->starget = starget; + schedule_work(&wqw->work); } /**