On Tue, Aug 7, 2018 at 8:27 PM, Bart Van Assche <bart.vanass...@wdc.com> wrote:
> On Tue, 2018-08-07 at 20:03 +0530, Sreekanth Reddy wrote:
>> The main intention of this patch to reset the smid to zero after
>> resetting the corresponding smid entry's chain_offset to zero. While
>> posting "mpt3sas: Fix calltrace observed while running IO & reset"
>> patch I have done manual mistake that I reset the smid to zero before
>> resetting the chain_offset which is wrong. Due to which driver
>> always's reset the chain_offset of zero th  entry of chain_lookup[]
>> table which is wrong and hence I am correcting it with this patch.
>>
>> After that you asked me to add memory barriers and hence I have added
>> memory barriers in subsequent versions of the patch.
>
> Hello Sreekanth,
>
> Please answer the questions I already asked you twice instead of sidestepping
> these.


Here I am copying your quires from your previous mails and I am
replaying inline..


In mpt3sas_base_get_smid_scsiio() I found the following code:

              struct scsiio_tracker *request = scsi_cmd_priv(scmd);
              u16 smid = scmd->request->tag + 1;
              request->smid = smid;

That confirms what you wrote about smid being unique for each I/O request.

However, this also raises new questions. As far as I can see all code
in the I/O path that accesses the chain_lookup[] array uses index smid
- 1.

[Sreekanth] Our IOC firmware always requires smid to be >=1, zero is
illegal smid for the IOC firmware. Hence while framing MPT SCSI IO
request driver always make sure that smid to be >=1, so it uses smid
as tag + 1.
where as chain_lookup[] starts with index zero, So driver is accessing
this chain_lookup[] with smid-1 index.


The patch at the start of this e-mail thread modifies two functions, namely

mpt3sas_remove_dead_ioc_func() and mpt3sas_base_clear_st(). Since the
chain_lookup[] array is indexed with the smid and hence contains
request- private data, how is it even possible that these functions
race against each other?
[Sreekanth] This patch modifies in two functions namely
'_base_get_chain_buffer_tracker()' & 'mpt3sas_base_clear_st()' not in
the mpt3sas_remove_dead_ioc_func(). Their is no race between
mpt3sas_remove_dead_ioc_func() & mpt3sas_base_clear_st(). Also their
is no race between _base_get_chain_buffer_tracker() &
mpt3sas_base_clear_st(), since for a particular IO
_base_get_chain_buffer_tracker() is called during IO submission time
for getting required chain buffer and mpt3sas_base_clear_st() is
called to free the used chain buffers in the IO completion path. Also
we have pre-allocated required chain buffers for each IO request and
hence no need to main any list and their is no race between these two
functions.

 Is there perhaps code that accesses the chain_lookup[] array and that
is called from another context than the I/O completion path?
[Sreekanth] No, it is called only from IO submission time.


Is the patch at the start of this e-mail thread the result of a
theoretical concern or of a real failure? In the latter case, which
sequence of actions triggered the failure? The answer to this question
should already have been mentioned in the description of v1 of this
patch
[Sreekanth] The main intention of this patch to reset the smid to zero
after resetting the corresponding smid entry's chain_offset to zero in
chain_lookup[]. While posting "mpt3sas: Fix calltrace observed while
running IO & reset" patch I have done manual mistake that I reset the
smid to zero before resetting the chain_offset which is wrong. Due to
which driver always's reset the chain_offset of zero th  entry of
chain_lookup[] table which is wrong and we may see that scmd's will be
returned from scsih_qcmd() with "host busy" status due to
unavailability of chain buffers (as driver is resetting the wrong
smid's i.e. zero th smid entry's chain_offset instead of correct smid
entry's chain_offset) and IO's will be in hung state .  So, I am
correcting it with this patch.
After that you asked me to add memory barriers and hence I have added
memory barriers in subsequent versions of the patch.


How can this patch be necessary if there are no races between I/O
submission and I/O completion?
[Sreekanth] As I explained above in this patch I am resetting the smid
variable to zero only after resetting the smid's chain_offset in
chain_lookup[] table. Due to manual mistake earlier I am resetting the
smid variable to zero before resetting the correct smid entry's
chain_offset in the chain_lookup[] table, which is wrong and I am
correcting it with this patch.

 Changing the order of two memory writes only makes sense if there is
a race condition involved. Since the block layer allocates a request
tag before scsih_qcmd() is called and since mpt3sas_base_free_smid()
is called before scmd->scsi_done(scmd) in _scsih_io_done(), the
request tag is freed after the smid has been freed when I/O completes
in a normal way. So there shouldn't be a race condition in that
scenario.
[Sreekanth] yes their is no race condition in this scenario.


By the way, you have not answered my question about why development of this
patch started. Does this patch address a theoretical concern or a real bug?
[Sreekanth] As I explained above while submitting "mpt3sas: Fix
calltrace observed while running IO & reset" patch I have made a
manual mistake that I am resetting the smid variable in wrong line in
mpt3sas_base_clear_st() function and I am correcting it with this
patch.

In the latter case, which scenario triggers the addressed bug?
[Sreekanth] Due to this manual mistake IO will be in hung state as
driver will return the scmd's with host busy status due to
unavailability of chain buffers after running IO for some time.

If you want this patch to go upstream you should be able to explain
why you think it is
useful, and that description should be included in the patch description.
[Sreekanth] In the patch description I mentioned that I have done a
manual mistake and I am correcting with this patch.


Hope I have answered all of your quires.

Thanks,
Sreekanth

>
> Thanks,
>
> Bart.
>

Reply via email to