Re: [PATCH] cifs: only wake the thread for the very last PDU in a compound

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Aug 30, 2018 at 9:01 AM, Pavel Shilovsky <piastryyy@xxxxxxxxx> wrote:
> ср, 29 авг. 2018 г. в 15:34, Pavel Shilovsky <piastryyy@xxxxxxxxx>:
>>
>> вт, 28 авг. 2018 г. в 19:19, Ronnie Sahlberg <lsahlber@xxxxxxxxxx>:
>> >
>> > For compounded PDUs we whould only wake the waiting thread for the
>> > very last PDU of the compound.
>> > We do this so that we are guaranteed that the demultiplex_thread will
>> > not process or access any of those MIDs any more once the send/recv
>> > thread starts processing.
>> >
>> > Else there is a race where at the end of the send/recv processing we
>> > will try to delete all the mids of the compound. If the multiplex
>> > thread still has other mids to process at this point for this compound
>> > this can lead to an oops.
>> >
>> > Signed-off-by: Ronnie Sahlberg <lsahlber@xxxxxxxxxx>
>> > ---
>> >  fs/cifs/transport.c | 19 ++++++++++++++++++-
>> >  1 file changed, 18 insertions(+), 1 deletion(-)
>> >
>> > diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
>> > index 9e3a1e87ae1c..49a800ce75d6 100644
>> > --- a/fs/cifs/transport.c
>> > +++ b/fs/cifs/transport.c
>> > @@ -773,6 +773,11 @@ cifs_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
>> >         return mid;
>> >  }
>> >
>> > +static void
>> > +cifs_noop_callback(struct mid_q_entry *mid)
>> > +{
>> > +}
>> > +
>> >  int
>> >  compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
>> >                    const int flags, const int num_rqst, struct smb_rqst *rqst,
>> > @@ -826,9 +831,15 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
>> >                         return PTR_ERR(midQ[i]);
>> >                 }
>> >
>> > +               /*
>> > +                * We don't invoke the callback compounds unless it is the last
>> > +                * request.
>> > +                */
>> >                 midQ[i]->mid_state = MID_REQUEST_SUBMITTED;
>> > +               if (ses->server->ops->next_header &&
>> > +                   ses->server->ops->next_header(rqst[i].rq_iov[0].iov_base))
>> > +                       midQ[i]->callback = cifs_noop_callback;
>>
>> Wouldn't it be easier to just check for i  < num_rqst - 1 ? Having
>> ses->server->ops->next_header(rqst[i].rq_iov[0].iov_base) return false
>> should be a bug here. SMB1 code doesn't support compounding at all, so
>> num_rqst is always 1.
>
> Also I thought that we may use a similar change you did in WIP patch -
> just set mids[i]->multiRsp and mids[i]->multiEnd properly for
> compounded requests. I mean the following:
>
> if (num_req > 1) {
>     mids[i]->multiRsp = 1;
>     if (i == num_req - 1) {
>         mids[i]->multiEnd = 1;
>     }
> }
>
> This will work for both compound and non-compound requests and utilize
> the existing multiRsp/multiEnd fields. Thoughts?

I don't think we can set those flags already in compound_send_recv
since that will affect other codepaths during send and receive, at
least handle_mid()
possibly other places too.

But your other suggestion to just look at num_rqst instead of checking
for and calling ->next_header makes sense. I will do that and re-send.

regards
ronnie sahlberg


>
> --
> Best regards,
> Pavel Shilovsky




[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux