On 02/17/2017 09:45 AM, Christoph Hellwig wrote:
> On Fri, Feb 17, 2017 at 09:23:07AM +0100, Hannes Reinecke wrote:
>> ioctl passthrough commands require a SCSIIO smid, but cannot
>> easily integrate with the block layer. But as we're only ever
>> allowing one ioctl command at a time we can reserve smid 1
>> for ioctl commands.
> 
> I like the idea, but I don't think the implementation is correct.
> More below.
> 
>> --- a/drivers/scsi/mpt3sas/mpt3sas_base.c
>> +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
>> @@ -2355,13 +2355,20 @@ struct scsiio_tracker *
>>              return 0;
>>      }
>>  
>> -    request = list_entry(ioc->free_list.next,
>> -        struct scsiio_tracker, tracker_list);
>> -    request->scmd = scmd;
>> +    if (!scmd) {
>> +            /* ioctl command, always use the first slot */
>> +            request = ioc->lookup[0];
>> +            request->scmd = NULL;
>> +    } else {
>> +            request = list_entry(ioc->free_list.next,
>> +                                 struct scsiio_tracker, tracker_list);
>> +            request->scmd = scmd;
>> +    }
>>      request->cb_idx = cb_idx;
>>      smid = request->smid;
>>      request->msix_io = _base_get_msix_index(ioc);
>> -    list_del(&request->tracker_list);
>> +    if (scmd)
>> +            list_del(&request->tracker_list);
>>      spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
>>      return smid;
> 
> The freelist check just before the patch context and the locking
> don't make much sense here.  I'd say just use a separate helper for the
> ioctl smid, ala:
> 
> u16
> mpt3sas_base_init_smid_pt(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx)
> {
>       struct scsiio_tracker *request = ioc->lookup[0];
> 
>       request->cb_idx = cb_idx;
>       request->msix_io = _base_get_msix_index(ioc);
>       return request->smid;
> }
> 
> or given how trivial this is just open-code it in the caller.
> 
> 
In principle, yes.
However, most of that is obsoleted when switching over to using reserved
commands in patch 11/11; then we properly register 'reserved' commands
with the block layer and this whole issue goes away.

>>              ioc->scsi_lookup[i].cb_idx = 0xFF;
>>              ioc->scsi_lookup[i].scmd = NULL;
>>              ioc->scsi_lookup[i].direct_io = 0;
>> -            list_add(&ioc->scsi_lookup[i].tracker_list, &ioc->free_list);
>> +            if (i > 0)
>> +                    list_add(&ioc->scsi_lookup[i].tracker_list,
>> +                             &ioc->free_list);
> 
> Here we special case only request 0 as not added to the list.
> 
>> @@ -5165,14 +5174,17 @@ struct scsiio_tracker *
>>      spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
>>      INIT_LIST_HEAD(&ioc->free_list);
>>      smid = 1;
>> -    for (i = 0; i < ioc->scsiio_depth; i++, smid++) {
>> +    for (i = 1; i < ioc->scsiio_depth; i++, smid++) {
>>              INIT_LIST_HEAD(&ioc->scsi_lookup[i].chain_list);
>>              ioc->scsi_lookup[i].cb_idx = 0xFF;
>>              ioc->scsi_lookup[i].smid = smid;
>>              ioc->scsi_lookup[i].scmd = NULL;
>>              ioc->scsi_lookup[i].direct_io = 0;
>> -            list_add_tail(&ioc->scsi_lookup[i].tracker_list,
>> -                &ioc->free_list);
>> +            if (i == 1)
>> +                    INIT_LIST_HEAD(&ioc->lookup[i].tracker_list);
>> +            else
>> +                    list_add_tail(&ioc->scsi_lookup[i].tracker_list,
>> +                                  &ioc->free_list);
> 
> And here we don't even iterate over smid 0, and then special case smid 1.
> 
> And note that the code in both loops is otherwise duplicated to start
> with and could realy use a little helper to initialize the scsiio_tracker
> structure.
> 
Again, most of that code will be obsoleted with patch 09/11, which
switches over to scsi-mq.
This whole code is just a band-aid until the driver is switched over to
scsi-mq, where we have correct allocation for reserved commands.
I just couldn't be bothered to implement reserved commands for legacy
sq, seeing that it'll be obsoleted at some point in the future anyway.

> Last but not least can_queue is initialized as:
> 
>         ioc->shost->can_queue = ioc->scsiio_depth - 
> INTERNAL_SCSIIO_CMDS_COUNT;
> 
> which doesn't take this new stolen smid into account.
> 
Thing is, the internal commands are _never_ used anywhere, so
'can_queue' is actually still correct :-)

Cheers,

Hannes
-- 
Dr. Hannes Reinecke                Teamlead Storage & Networking
[email protected]                                   +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

Reply via email to