aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/device_handler
diff options
context:
space:
mode:
authorMoger, Babu2012-03-27 20:56:20 +0000
committerJames Bottomley2012-04-23 19:28:18 +0100
commit72d9e0f383c2b7a2e2fe4442577319bae0686f40 (patch)
treeb2b189795687b7cfd179351d4e31e05c501ff817 /drivers/scsi/device_handler
parentdcd3a754b8c811441326d68574598fb3b4976ff4 (diff)
[SCSI] scsi_dh_alua: Optimize the STPG command
This patch optimizes the set target port group(STPG) command. During our testing, we found that it is not optimal to send stpg command every time the path group switch happens. This patch uses PREF (preferred target port) bit with combination of flags passed by multipath user level tool to optimize this behaviour. If PREF bit is set then it issues a STPG command, otherwise it will let implicit transfer take place. By default there is no change in the behaviour. User tool needs to pass the parameter to make this change take effect. Patch has been tested on NetApp E series storage. Signed-off-by: Babu Moger <babu.moger@netapp.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/device_handler')
-rw-r--r--drivers/scsi/device_handler/scsi_dh_alua.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index 4865a99d9c38..fda9cdea0e60 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -675,14 +675,37 @@ static int alua_activate(struct scsi_device *sdev,
{
struct alua_dh_data *h = get_alua_data(sdev);
int err = SCSI_DH_OK;
+ int stpg = 0;
err = alua_rtpg(sdev, h);
if (err != SCSI_DH_OK)
goto out;
- if (h->tpgs & TPGS_MODE_EXPLICIT &&
- h->state != TPGS_STATE_OPTIMIZED &&
- h->state != TPGS_STATE_LBA_DEPENDENT) {
+ if (h->tpgs & TPGS_MODE_EXPLICIT) {
+ switch (h->state) {
+ case TPGS_STATE_NONOPTIMIZED:
+ stpg = 1;
+ if ((h->flags & ALUA_OPTIMIZE_STPG) &&
+ (!h->pref) &&
+ (h->tpgs & TPGS_MODE_IMPLICIT))
+ stpg = 0;
+ break;
+ case TPGS_STATE_STANDBY:
+ stpg = 1;
+ break;
+ case TPGS_STATE_UNAVAILABLE:
+ case TPGS_STATE_OFFLINE:
+ err = SCSI_DH_IO;
+ break;
+ case TPGS_STATE_TRANSITIONING:
+ err = SCSI_DH_RETRY;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (stpg) {
h->callback_fn = fn;
h->callback_data = data;
err = submit_stpg(h);