aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghava Aditya Renukunta <raghavaaditya.renukunta@pmcs.com>2016-02-03 18:05:59 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2016-02-23 21:27:02 -0500
commit6bf3b630d0a733b74f7167a1cfac457358e67074 (patch)
tree59da3397e5e1d5ad5a4e7733bc1604a9d6e88247
parentbd8d859a21b422c71bee45ec9e54251aecfdcb5c (diff)
aacraid: SCSI blk tag support
The method to allocate and free FIB's in the present code utilizes spinlocks. Multiple IO's have to wait on the spinlock to acquire or free fibs creating a performance bottleneck. An alternative solution would be to use block layer tags to keep track of the fibs allocated and freed. To this end aac_fib_alloc_tag was created to utilize the blk layer tags to plug into the Fib pool.These functions are used exclusively in the IO path. 8 fibs are reserved for the use of AIF management software and utilize the previous spinlock based implementations. Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@pmcs.com> Reviewed-by: Shane Seymour <shane.seymour@hpe.com> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> Reviewed-by: Tomas Henzl <thenzl@redhat.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/aacraid/aachba.c27
-rw-r--r--drivers/scsi/aacraid/aacraid.h1
-rw-r--r--drivers/scsi/aacraid/commsup.c32
-rw-r--r--drivers/scsi/aacraid/dpcsup.c2
-rw-r--r--drivers/scsi/aacraid/linit.c2
5 files changed, 44 insertions, 20 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index e4c243748a97..7dfd0fa27255 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -323,7 +323,6 @@ static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
323 if (unlikely(!scsicmd || !scsicmd->scsi_done)) { 323 if (unlikely(!scsicmd || !scsicmd->scsi_done)) {
324 dprintk((KERN_WARNING "aac_valid_context: scsi command corrupt\n")); 324 dprintk((KERN_WARNING "aac_valid_context: scsi command corrupt\n"));
325 aac_fib_complete(fibptr); 325 aac_fib_complete(fibptr);
326 aac_fib_free(fibptr);
327 return 0; 326 return 0;
328 } 327 }
329 scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; 328 scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;
@@ -331,7 +330,6 @@ static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
331 if (unlikely(!device || !scsi_device_online(device))) { 330 if (unlikely(!device || !scsi_device_online(device))) {
332 dprintk((KERN_WARNING "aac_valid_context: scsi device corrupt\n")); 331 dprintk((KERN_WARNING "aac_valid_context: scsi device corrupt\n"));
333 aac_fib_complete(fibptr); 332 aac_fib_complete(fibptr);
334 aac_fib_free(fibptr);
335 return 0; 333 return 0;
336 } 334 }
337 return 1; 335 return 1;
@@ -541,7 +539,6 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
541 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; 539 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
542 540
543 aac_fib_complete(fibptr); 541 aac_fib_complete(fibptr);
544 aac_fib_free(fibptr);
545 scsicmd->scsi_done(scsicmd); 542 scsicmd->scsi_done(scsicmd);
546} 543}
547 544
@@ -557,7 +554,8 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd)
557 554
558 dev = (struct aac_dev *)scsicmd->device->host->hostdata; 555 dev = (struct aac_dev *)scsicmd->device->host->hostdata;
559 556
560 if (!(cmd_fibcontext = aac_fib_alloc(dev))) 557 cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
558 if (!cmd_fibcontext)
561 return -ENOMEM; 559 return -ENOMEM;
562 560
563 aac_fib_init(cmd_fibcontext); 561 aac_fib_init(cmd_fibcontext);
@@ -586,7 +584,6 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd)
586 584
587 printk(KERN_WARNING "aac_get_container_name: aac_fib_send failed with status: %d.\n", status); 585 printk(KERN_WARNING "aac_get_container_name: aac_fib_send failed with status: %d.\n", status);
588 aac_fib_complete(cmd_fibcontext); 586 aac_fib_complete(cmd_fibcontext);
589 aac_fib_free(cmd_fibcontext);
590 return -1; 587 return -1;
591} 588}
592 589
@@ -1024,7 +1021,6 @@ static void get_container_serial_callback(void *context, struct fib * fibptr)
1024 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; 1021 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
1025 1022
1026 aac_fib_complete(fibptr); 1023 aac_fib_complete(fibptr);
1027 aac_fib_free(fibptr);
1028 scsicmd->scsi_done(scsicmd); 1024 scsicmd->scsi_done(scsicmd);
1029} 1025}
1030 1026
@@ -1040,7 +1036,8 @@ static int aac_get_container_serial(struct scsi_cmnd * scsicmd)
1040 1036
1041 dev = (struct aac_dev *)scsicmd->device->host->hostdata; 1037 dev = (struct aac_dev *)scsicmd->device->host->hostdata;
1042 1038
1043 if (!(cmd_fibcontext = aac_fib_alloc(dev))) 1039 cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
1040 if (!cmd_fibcontext)
1044 return -ENOMEM; 1041 return -ENOMEM;
1045 1042
1046 aac_fib_init(cmd_fibcontext); 1043 aac_fib_init(cmd_fibcontext);
@@ -1068,7 +1065,6 @@ static int aac_get_container_serial(struct scsi_cmnd * scsicmd)
1068 1065
1069 printk(KERN_WARNING "aac_get_container_serial: aac_fib_send failed with status: %d.\n", status); 1066 printk(KERN_WARNING "aac_get_container_serial: aac_fib_send failed with status: %d.\n", status);
1070 aac_fib_complete(cmd_fibcontext); 1067 aac_fib_complete(cmd_fibcontext);
1071 aac_fib_free(cmd_fibcontext);
1072 return -1; 1068 return -1;
1073} 1069}
1074 1070
@@ -1869,7 +1865,6 @@ static void io_callback(void *context, struct fib * fibptr)
1869 break; 1865 break;
1870 } 1866 }
1871 aac_fib_complete(fibptr); 1867 aac_fib_complete(fibptr);
1872 aac_fib_free(fibptr);
1873 1868
1874 scsicmd->scsi_done(scsicmd); 1869 scsicmd->scsi_done(scsicmd);
1875} 1870}
@@ -1954,7 +1949,8 @@ static int aac_read(struct scsi_cmnd * scsicmd)
1954 /* 1949 /*
1955 * Alocate and initialize a Fib 1950 * Alocate and initialize a Fib
1956 */ 1951 */
1957 if (!(cmd_fibcontext = aac_fib_alloc(dev))) { 1952 cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
1953 if (!cmd_fibcontext) {
1958 printk(KERN_WARNING "aac_read: fib allocation failed\n"); 1954 printk(KERN_WARNING "aac_read: fib allocation failed\n");
1959 return -1; 1955 return -1;
1960 } 1956 }
@@ -2051,7 +2047,8 @@ static int aac_write(struct scsi_cmnd * scsicmd)
2051 /* 2047 /*
2052 * Allocate and initialize a Fib then setup a BlockWrite command 2048 * Allocate and initialize a Fib then setup a BlockWrite command
2053 */ 2049 */
2054 if (!(cmd_fibcontext = aac_fib_alloc(dev))) { 2050 cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
2051 if (!cmd_fibcontext) {
2055 /* FIB temporarily unavailable,not catastrophic failure */ 2052 /* FIB temporarily unavailable,not catastrophic failure */
2056 2053
2057 /* scsicmd->result = DID_ERROR << 16; 2054 /* scsicmd->result = DID_ERROR << 16;
@@ -2285,7 +2282,7 @@ static int aac_start_stop(struct scsi_cmnd *scsicmd)
2285 /* 2282 /*
2286 * Allocate and initialize a Fib 2283 * Allocate and initialize a Fib
2287 */ 2284 */
2288 cmd_fibcontext = aac_fib_alloc(aac); 2285 cmd_fibcontext = aac_fib_alloc_tag(aac, scsicmd);
2289 if (!cmd_fibcontext) 2286 if (!cmd_fibcontext)
2290 return SCSI_MLQUEUE_HOST_BUSY; 2287 return SCSI_MLQUEUE_HOST_BUSY;
2291 2288
@@ -3157,7 +3154,6 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
3157 scsicmd->result |= le32_to_cpu(srbreply->scsi_status); 3154 scsicmd->result |= le32_to_cpu(srbreply->scsi_status);
3158 3155
3159 aac_fib_complete(fibptr); 3156 aac_fib_complete(fibptr);
3160 aac_fib_free(fibptr);
3161 scsicmd->scsi_done(scsicmd); 3157 scsicmd->scsi_done(scsicmd);
3162} 3158}
3163 3159
@@ -3187,9 +3183,10 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
3187 /* 3183 /*
3188 * Allocate and initialize a Fib then setup a BlockWrite command 3184 * Allocate and initialize a Fib then setup a BlockWrite command
3189 */ 3185 */
3190 if (!(cmd_fibcontext = aac_fib_alloc(dev))) { 3186 cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
3187 if (!cmd_fibcontext)
3191 return -1; 3188 return -1;
3192 } 3189
3193 status = aac_adapter_scsi(cmd_fibcontext, scsicmd); 3190 status = aac_adapter_scsi(cmd_fibcontext, scsicmd);
3194 3191
3195 /* 3192 /*
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 074878b55a0b..f51f0a009574 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -2114,6 +2114,7 @@ int aac_acquire_irq(struct aac_dev *dev);
2114void aac_free_irq(struct aac_dev *dev); 2114void aac_free_irq(struct aac_dev *dev);
2115const char *aac_driverinfo(struct Scsi_Host *); 2115const char *aac_driverinfo(struct Scsi_Host *);
2116struct fib *aac_fib_alloc(struct aac_dev *dev); 2116struct fib *aac_fib_alloc(struct aac_dev *dev);
2117struct fib *aac_fib_alloc_tag(struct aac_dev *dev, struct scsi_cmnd *scmd);
2117int aac_fib_setup(struct aac_dev *dev); 2118int aac_fib_setup(struct aac_dev *dev);
2118void aac_fib_map_free(struct aac_dev *dev); 2119void aac_fib_map_free(struct aac_dev *dev);
2119void aac_fib_free(struct fib * context); 2120void aac_fib_free(struct fib * context);
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index a1f90fe849c9..46a2a2f77db3 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -137,6 +137,7 @@ int aac_fib_setup(struct aac_dev * dev)
137 i++, fibptr++) 137 i++, fibptr++)
138 { 138 {
139 fibptr->flags = 0; 139 fibptr->flags = 0;
140 fibptr->size = sizeof(struct fib);
140 fibptr->dev = dev; 141 fibptr->dev = dev;
141 fibptr->hw_fib_va = hw_fib; 142 fibptr->hw_fib_va = hw_fib;
142 fibptr->data = (void *) fibptr->hw_fib_va->data; 143 fibptr->data = (void *) fibptr->hw_fib_va->data;
@@ -156,13 +157,38 @@ int aac_fib_setup(struct aac_dev * dev)
156 */ 157 */
157 dev->fibs[dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB - 1].next = NULL; 158 dev->fibs[dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB - 1].next = NULL;
158 /* 159 /*
159 * Enable this to debug out of queue space 160 * Set 8 fibs aside for management tools
160 */ 161 */
161 dev->free_fib = &dev->fibs[0]; 162 dev->free_fib = &dev->fibs[dev->scsi_host_ptr->can_queue];
162 return 0; 163 return 0;
163} 164}
164 165
165/** 166/**
167 * aac_fib_alloc_tag-allocate a fib using tags
168 * @dev: Adapter to allocate the fib for
169 *
170 * Allocate a fib from the adapter fib pool using tags
171 * from the blk layer.
172 */
173
174struct fib *aac_fib_alloc_tag(struct aac_dev *dev, struct scsi_cmnd *scmd)
175{
176 struct fib *fibptr;
177
178 fibptr = &dev->fibs[scmd->request->tag];
179 /*
180 * Null out fields that depend on being zero at the start of
181 * each I/O
182 */
183 fibptr->hw_fib_va->header.XferState = 0;
184 fibptr->type = FSAFS_NTC_FIB_CONTEXT;
185 fibptr->callback_data = NULL;
186 fibptr->callback = NULL;
187
188 return fibptr;
189}
190
191/**
166 * aac_fib_alloc - allocate a fib 192 * aac_fib_alloc - allocate a fib
167 * @dev: Adapter to allocate the fib for 193 * @dev: Adapter to allocate the fib for
168 * 194 *
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c
index da9d9936e995..d677b52860ae 100644
--- a/drivers/scsi/aacraid/dpcsup.c
+++ b/drivers/scsi/aacraid/dpcsup.c
@@ -394,7 +394,6 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index,
394 fib->callback(fib->callback_data, fib); 394 fib->callback(fib->callback_data, fib);
395 } else { 395 } else {
396 aac_fib_complete(fib); 396 aac_fib_complete(fib);
397 aac_fib_free(fib);
398 } 397 }
399 } else { 398 } else {
400 unsigned long flagv; 399 unsigned long flagv;
@@ -416,7 +415,6 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index,
416 fib->done = 0; 415 fib->done = 0;
417 spin_unlock_irqrestore(&fib->event_lock, flagv); 416 spin_unlock_irqrestore(&fib->event_lock, flagv);
418 aac_fib_complete(fib); 417 aac_fib_complete(fib);
419 aac_fib_free(fib);
420 } 418 }
421 419
422 } 420 }
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 76eaa38ffd6e..129a515c7e49 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -454,6 +454,8 @@ static int aac_slave_configure(struct scsi_device *sdev)
454 } else 454 } else
455 scsi_change_queue_depth(sdev, 1); 455 scsi_change_queue_depth(sdev, 1);
456 456
457 sdev->tagged_supported = 1;
458
457 return 0; 459 return 0;
458} 460}
459 461