Message ID | CA+jPhpdaRamMOEeuqHg13Ris3TXPdUVJ-fxjKzPsFt7nv-Tejg@mail.gmail.com |
---|---|
State | New |
Headers | show |
Series | Fixes for LP1801686 [v2] | expand |
On 11/06/18 16:24, Frank Heimes wrote: > From: Julian Wiedmann <jwi@linux.ibm.com <mailto:jwi@linux.ibm.com>> > > BugLink: http://bugs.launchpad.net/bugs/1801686 > > s390/qdio: reset old sbal_state flags > > When allocating a new AOB fails, handle_outbound() is still capable of > transmitting the selected buffer (just without async completion). > > But if a previous transfer on this queue slot used async completion, its > sbal_state flags field is still set to QDIO_OUTBUF_STATE_FLAG_PENDING. > So when the upper layer driver sees this stale flag, it expects an async > completion that never happens. > > Fix this by unconditionally clearing the flags field. > > Fixes: 104ea556ee7f ("qdio: support asynchronous delivery of storage > blocks") > Cc: <stable@vger.kernel.org <mailto:stable@vger.kernel.org>> #v3.2+ > Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com > <mailto:jwi@linux.ibm.com>> > Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com > <mailto:schwidefsky@de.ibm.com>> > (cherry picked from commit 64e03ff72623b8c2ea89ca3cb660094e019ed4ae) > Signed-off-by: Frank Heimes <frank.heimes@canonical.com > <mailto:frank.heimes@canonical.com>> Clean cherry-pick and limited to vendor architecture. The html part will need to be removed when applying the patch (or cherry-pick it from upstream). Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com> > > --- > > diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h > index de11ecc..9c9970a 100644 > --- a/arch/s390/include/asm/qdio.h > +++ b/arch/s390/include/asm/qdio.h > @@ -262,7 +262,6 @@ struct qdio_outbuf_state { > void *user; > }; > > -#define QDIO_OUTBUF_STATE_FLAG_NONE 0x00 > #define QDIO_OUTBUF_STATE_FLAG_PENDING 0x01 > > #define CHSC_AC1_INITIATE_INPUTQ 0x80 > diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c > index f4ca72d..9c7d9da 100644 > --- a/drivers/s390/cio/qdio_main.c > +++ b/drivers/s390/cio/qdio_main.c > @@ -631,21 +631,20 @@ static inline unsigned long > qdio_aob_for_buffer(struct qdio_output_q *q, > unsigned long phys_aob = 0; > > if (!q->use_cq) > - goto out; > + return 0; > > if (!q->aobs[bufnr]) { > struct qaob *aob = qdio_allocate_aob(); > q->aobs[bufnr] = aob; > } > if (q->aobs[bufnr]) { > - q->sbal_state[bufnr].flags = QDIO_OUTBUF_STATE_FLAG_NONE; > q->sbal_state[bufnr].aob = q->aobs[bufnr]; > q->aobs[bufnr]->user1 = (u64) q->sbal_state[bufnr].user; > phys_aob = virt_to_phys(q->aobs[bufnr]); > WARN_ON_ONCE(phys_aob & 0xFF); > } > > -out: > + q->sbal_state[bufnr].flags = 0; > return phys_aob; > } > >
On 06.11.18 16:24, Frank Heimes wrote: > From: Julian Wiedmann <jwi@linux.ibm.com <mailto:jwi@linux.ibm.com>> > > BugLink: http://bugs.launchpad.net/bugs/1801686 > > s390/qdio: reset old sbal_state flags > > When allocating a new AOB fails, handle_outbound() is still capable of > transmitting the selected buffer (just without async completion). > > But if a previous transfer on this queue slot used async completion, its > sbal_state flags field is still set to QDIO_OUTBUF_STATE_FLAG_PENDING. > So when the upper layer driver sees this stale flag, it expects an async > completion that never happens. > > Fix this by unconditionally clearing the flags field. > > Fixes: 104ea556ee7f ("qdio: support asynchronous delivery of storage blocks") > Cc: <stable@vger.kernel.org <mailto:stable@vger.kernel.org>> #v3.2+ > Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com <mailto:jwi@linux.ibm.com>> > Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com > <mailto:schwidefsky@de.ibm.com>> > (cherry picked from commit 64e03ff72623b8c2ea89ca3cb660094e019ed4ae) > Signed-off-by: Frank Heimes <frank.heimes@canonical.com > <mailto:frank.heimes@canonical.com>> Acked-by: Stefan Bader <stefan.bader@canonical.com> > > --- As Kleber also said, those HTML emails get annoying. Frank, you should seriously work on fixing that. -Stefan > > diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h > index de11ecc..9c9970a 100644 > --- a/arch/s390/include/asm/qdio.h > +++ b/arch/s390/include/asm/qdio.h > @@ -262,7 +262,6 @@ struct qdio_outbuf_state { > void *user; > }; > > -#define QDIO_OUTBUF_STATE_FLAG_NONE 0x00 > #define QDIO_OUTBUF_STATE_FLAG_PENDING 0x01 > > #define CHSC_AC1_INITIATE_INPUTQ 0x80 > diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c > index f4ca72d..9c7d9da 100644 > --- a/drivers/s390/cio/qdio_main.c > +++ b/drivers/s390/cio/qdio_main.c > @@ -631,21 +631,20 @@ static inline unsigned long qdio_aob_for_buffer(struct > qdio_output_q *q, > unsigned long phys_aob = 0; > > if (!q->use_cq) > - goto out; > + return 0; > > if (!q->aobs[bufnr]) { > struct qaob *aob = qdio_allocate_aob(); > q->aobs[bufnr] = aob; > } > if (q->aobs[bufnr]) { > - q->sbal_state[bufnr].flags = QDIO_OUTBUF_STATE_FLAG_NONE; > q->sbal_state[bufnr].aob = q->aobs[bufnr]; > q->aobs[bufnr]->user1 = (u64) q->sbal_state[bufnr].user; > phys_aob = virt_to_phys(q->aobs[bufnr]); > WARN_ON_ONCE(phys_aob & 0xFF); > } > > -out: > + q->sbal_state[bufnr].flags = 0; > return phys_aob; > } >
diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h index de11ecc..9c9970a 100644 --- a/arch/s390/include/asm/qdio.h +++ b/arch/s390/include/asm/qdio.h @@ -262,7 +262,6 @@ struct qdio_outbuf_state { void *user; }; -#define QDIO_OUTBUF_STATE_FLAG_NONE 0x00 #define QDIO_OUTBUF_STATE_FLAG_PENDING 0x01 #define CHSC_AC1_INITIATE_INPUTQ 0x80 diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index f4ca72d..9c7d9da 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -631,21 +631,20 @@ static inline unsigned long qdio_aob_for_buffer(struct qdio_output_q *q, unsigned long phys_aob = 0; if (!q->use_cq) - goto out; + return 0; if (!q->aobs[bufnr]) { struct qaob *aob = qdio_allocate_aob(); q->aobs[bufnr] = aob; } if (q->aobs[bufnr]) { - q->sbal_state[bufnr].flags = QDIO_OUTBUF_STATE_FLAG_NONE; q->sbal_state[bufnr].aob = q->aobs[bufnr]; q->aobs[bufnr]->user1 = (u64) q->sbal_state[bufnr].user; phys_aob = virt_to_phys(q->aobs[bufnr]); WARN_ON_ONCE(phys_aob & 0xFF); } -out: + q->sbal_state[bufnr].flags = 0; return phys_aob; }