From: Patrick Mansfield <patmans@us.ibm.com>
To: James Bottomley <James.Bottomley@steeleye.com>,
linux-scsi@vger.kernel.org
Subject: [patch] 1/5 scsi-locking-2.5 single_lun store scsi_device pointer
Date: Wed, 9 Apr 2003 16:46:12 -0700 [thread overview]
Message-ID: <20030409164612.A23701@beaverton.ibm.com> (raw)
Change single_lun code to use a struct scsi_device *, so that we do not
need an sdev (or queue_lock) while checking if a single_lun target is in
use by a particular scsi_device.
diff -purN -X /home/patman/dontdiff sl-base-2.5/drivers/scsi/scsi.h 01_slun_mod/drivers/scsi/scsi.h
--- sl-base-2.5/drivers/scsi/scsi.h Wed Apr 9 11:34:36 2003
+++ 01_slun_mod/drivers/scsi/scsi.h Wed Apr 9 12:39:15 2003
@@ -532,10 +532,11 @@ extern int scsi_dev_info_list_add_str(ch
/*
* scsi_target: representation of a scsi target, for now, this is only
- * used for single_lun devices.
+ * used for single_lun devices. If no one has active IO to the target,
+ * starget_sdev_user is NULL, else it points to the active sdev.
*/
struct scsi_target {
- unsigned int starget_busy;
+ struct scsi_device *starget_sdev_user;
unsigned int starget_refcnt;
};
diff -purN -X /home/patman/dontdiff sl-base-2.5/drivers/scsi/scsi_lib.c 01_slun_mod/drivers/scsi/scsi_lib.c
--- sl-base-2.5/drivers/scsi/scsi_lib.c Wed Apr 9 11:34:37 2003
+++ 01_slun_mod/drivers/scsi/scsi_lib.c Wed Apr 9 12:39:15 2003
@@ -327,9 +327,9 @@ void scsi_setup_cmd_retry(struct scsi_cm
}
/*
- * Called for single_lun devices on IO completion. Clear starget_busy, and
- * Call __blk_run_queue for all the scsi_devices on the target - including
- * current_sdev first.
+ * Called for single_lun devices on IO completion. Clear starget_sdev_user,
+ * and call __blk_run_queue for all the scsi_devices on the target -
+ * including current_sdev first.
*
* Called with *no* scsi locks held.
*/
@@ -338,19 +338,33 @@ static void scsi_single_lun_run(struct s
struct scsi_device *sdev;
unsigned int flags, flags2;
- spin_lock_irqsave(current_sdev->request_queue->queue_lock, flags2);
spin_lock_irqsave(current_sdev->host->host_lock, flags);
- WARN_ON(!current_sdev->sdev_target->starget_busy);
- if (current_sdev->device_busy == 0)
- current_sdev->sdev_target->starget_busy = 0;
+ WARN_ON(!current_sdev->sdev_target->starget_sdev_user);
+ current_sdev->sdev_target->starget_sdev_user = NULL;
spin_unlock_irqrestore(current_sdev->host->host_lock, flags);
/*
* Call __blk_run_queue for all LUNs on the target, starting with
- * current_sdev.
+ * current_sdev. We race with others (to set starget_sdev_user),
+ * but in most cases, we will be first. Ideally, each LU on the
+ * target would get some limited time or requests on the target.
*/
+ spin_lock_irqsave(current_sdev->request_queue->queue_lock, flags2);
__blk_run_queue(current_sdev->request_queue);
spin_unlock_irqrestore(current_sdev->request_queue->queue_lock, flags2);
+
+ spin_lock_irqsave(current_sdev->host->host_lock, flags);
+ if (current_sdev->sdev_target->starget_sdev_user) {
+ /*
+ * After unlock, this races with anyone clearing
+ * starget_sdev_user, but we (should) always enter this
+ * function again, avoiding any problems.
+ */
+ spin_unlock_irqrestore(current_sdev->host->host_lock, flags);
+ return;
+ }
+ spin_unlock_irqrestore(current_sdev->host->host_lock, flags);
+
list_for_each_entry(sdev, ¤t_sdev->same_target_siblings,
same_target_siblings) {
spin_lock_irqsave(sdev->request_queue->queue_lock, flags2);
@@ -1158,8 +1172,8 @@ static void scsi_request_fn(request_queu
if (!scsi_host_queue_ready(q, shost, sdev))
goto after_host_lock;
- if (sdev->single_lun && !sdev->device_busy &&
- sdev->sdev_target->starget_busy)
+ if (sdev->single_lun && sdev->sdev_target->starget_sdev_user &&
+ (sdev->sdev_target->starget_sdev_user != sdev))
goto after_host_lock;
/*
@@ -1198,7 +1212,7 @@ static void scsi_request_fn(request_queu
blkdev_dequeue_request(req);
if (sdev->single_lun)
- sdev->sdev_target->starget_busy = 1;
+ sdev->sdev_target->starget_sdev_user = sdev;
shost->host_busy++;
spin_unlock_irqrestore(shost->host_lock, flags);
diff -purN -X /home/patman/dontdiff sl-base-2.5/drivers/scsi/scsi_scan.c 01_slun_mod/drivers/scsi/scsi_scan.c
--- sl-base-2.5/drivers/scsi/scsi_scan.c Wed Apr 9 11:34:37 2003
+++ 01_slun_mod/drivers/scsi/scsi_scan.c Wed Apr 9 12:39:15 2003
@@ -1283,7 +1283,7 @@ static int scsi_add_lun(Scsi_Device *sde
return SCSI_SCAN_NO_RESPONSE;
}
starget->starget_refcnt = 0;
- starget->starget_busy = 0;
+ starget->starget_sdev_user = NULL;
}
starget->starget_refcnt++;
sdev->sdev_target = starget;
next reply other threads:[~2003-04-09 23:38 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-04-09 23:46 Patrick Mansfield [this message]
2003-04-09 23:47 ` [patch] 2/5 scsi-locking-2.5 remove lock hierarchy Patrick Mansfield
2003-04-09 23:47 ` [patch] 3/5 scsi-locking-2.5 prevent looping when processing starved queues Patrick Mansfield
2003-04-09 23:47 ` [patch] 4/5 scsi-locking-2.5 list_del starved_entry plus use GFP_ATOMIC Patrick Mansfield
2003-04-09 23:48 ` [patch] 5/5 scsi-locking-2.5 remove extra sdev2, remove extra logging Patrick Mansfield
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20030409164612.A23701@beaverton.ibm.com \
--to=patmans@us.ibm.com \
--cc=James.Bottomley@steeleye.com \
--cc=linux-scsi@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox