]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
IB/hfi1: Handle port down properly in pio
authorMike Marciniszyn <mike.marciniszyn@intel.com>
Fri, 14 Jun 2019 16:33:06 +0000 (12:33 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 27 Jan 2020 13:50:56 +0000 (14:50 +0100)
[ Upstream commit 942a899335707fc9cfc97cb382a60734b2ff4e03 ]

The call to sc_buffer_alloc currently returns NULL (no buffer) or
a buffer descriptor.

There is a third case when the port is down.  Currently that
returns NULL and this prevents the caller from properly handling the
sc_buffer_alloc() failure.  A verbs code link test after the call is
racy so the indication needs to come from the state check inside the allocation
routine to be valid.

Fix by encoding the ECOMM failure like SDMA.   IS_ERR_OR_NULL() tests
are added at all call sites.  For verbs send, this needs to treat any
error by returning a completion without any MMIO copy.

Fixes: 7724105686e7 ("IB/hfi1: add driver files")
Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/infiniband/hw/hfi1/pio.c
drivers/infiniband/hw/hfi1/rc.c
drivers/infiniband/hw/hfi1/ud.c
drivers/infiniband/hw/hfi1/verbs.c

index 752057647f091734368f998c0173234d8a1f2dd0..3fcbf56f8be23da344294e400fb30035fe7c0c14 100644 (file)
@@ -1434,7 +1434,8 @@ void sc_stop(struct send_context *sc, int flag)
  * @cb: optional callback to call when the buffer is finished sending
  * @arg: argument for cb
  *
- * Return a pointer to a PIO buffer if successful, NULL if not enough room.
+ * Return a pointer to a PIO buffer, NULL if not enough room, -ECOMM
+ * when link is down.
  */
 struct pio_buf *sc_buffer_alloc(struct send_context *sc, u32 dw_len,
                                pio_release_cb cb, void *arg)
@@ -1450,7 +1451,7 @@ struct pio_buf *sc_buffer_alloc(struct send_context *sc, u32 dw_len,
        spin_lock_irqsave(&sc->alloc_lock, flags);
        if (!(sc->flags & SCF_ENABLED)) {
                spin_unlock_irqrestore(&sc->alloc_lock, flags);
-               goto done;
+               return ERR_PTR(-ECOMM);
        }
 
 retry:
index 980168a56707142a2f9f1fef8ee9ef84f352e803..7ed6fb407a689243cb55778ea4d8ca7c1f41ec7a 100644 (file)
@@ -914,7 +914,7 @@ void hfi1_send_rc_ack(struct hfi1_packet *packet, bool is_fecn)
        pbc = create_pbc(ppd, pbc_flags, qp->srate_mbps,
                         sc_to_vlt(ppd->dd, sc5), plen);
        pbuf = sc_buffer_alloc(rcd->sc, plen, NULL, NULL);
-       if (!pbuf) {
+       if (IS_ERR_OR_NULL(pbuf)) {
                /*
                 * We have no room to send at the moment.  Pass
                 * responsibility for sending the ACK to the send engine
index ef5b3ffd3888b440569e3013bba2e96962312641..839593641e3fd4eb7ab131a84d0f373f22955bac 100644 (file)
@@ -703,7 +703,7 @@ void return_cnp_16B(struct hfi1_ibport *ibp, struct rvt_qp *qp,
        pbc = create_pbc(ppd, pbc_flags, qp->srate_mbps, vl, plen);
        if (ctxt) {
                pbuf = sc_buffer_alloc(ctxt, plen, NULL, NULL);
-               if (pbuf) {
+               if (!IS_ERR_OR_NULL(pbuf)) {
                        trace_pio_output_ibhdr(ppd->dd, &hdr, sc5);
                        ppd->dd->pio_inline_send(ppd->dd, pbuf, pbc,
                                                 &hdr, hwords);
@@ -758,7 +758,7 @@ void return_cnp(struct hfi1_ibport *ibp, struct rvt_qp *qp, u32 remote_qpn,
        pbc = create_pbc(ppd, pbc_flags, qp->srate_mbps, vl, plen);
        if (ctxt) {
                pbuf = sc_buffer_alloc(ctxt, plen, NULL, NULL);
-               if (pbuf) {
+               if (!IS_ERR_OR_NULL(pbuf)) {
                        trace_pio_output_ibhdr(ppd->dd, &hdr, sc5);
                        ppd->dd->pio_inline_send(ppd->dd, pbuf, pbc,
                                                 &hdr, hwords);
index 4e7b3c027901bd21fec925ef029cb471a1cc887c..90e12f9433a39e42563d5dbdd2ed5876833ad70c 100644 (file)
@@ -1096,10 +1096,10 @@ int hfi1_verbs_send_pio(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
        if (cb)
                iowait_pio_inc(&priv->s_iowait);
        pbuf = sc_buffer_alloc(sc, plen, cb, qp);
-       if (unlikely(!pbuf)) {
+       if (unlikely(IS_ERR_OR_NULL(pbuf))) {
                if (cb)
                        verbs_pio_complete(qp, 0);
-               if (ppd->host_link_state != HLS_UP_ACTIVE) {
+               if (IS_ERR(pbuf)) {
                        /*
                         * If we have filled the PIO buffers to capacity and are
                         * not in an active state this request is not going to