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]

 



ср, 29 авг. 2018 г. в 16:13, ronnie sahlberg <ronniesahlberg@xxxxxxxxx>:
>
> 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.
>

Actually, it does seem that handle_mid() is the only place that
behaves differently depending on those flags. We could add another
mid->compound flag to check in handle_mid(). But anyway, that will
probably complicate things more because for SMB1 multiRsp/multiEnd
flags serve slightly another purpose. Agree, let's do indices check
instead.

--
Best regards,
Pavel Shilovsky




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

  Powered by Linux