]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
IB/hfi1: Eliminate allocation while atomic
authorDon Hiatt <don.hiatt@intel.com>
Mon, 9 Oct 2017 19:38:19 +0000 (12:38 -0700)
committerDoug Ledford <dledford@redhat.com>
Wed, 18 Oct 2017 14:12:59 +0000 (10:12 -0400)
The PIO trailing buffer was being dynamically allocated
but the kcalloc return value was not being checked. Further,
the GFP_KERNEL was being used even though the send engine
might be called with interrupts disabled.

Since the maximum size of the trailing buffer is only 12
bytes (CRC = 4, LT = 1, Pad = 0 to 7 bytes) just statically
allocate the buffer, remove the alloc entirely and share it
with the SDMA engine by making it global.

Reported-by: Leon Romanovsky <leon@kernel.org>
Fixes: 566d53a82644 ("IB/hfi1: Enhance PIO/SDMA send for 16B")
Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: Don Hiatt <don.hiatt@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Reviewed-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/hw/hfi1/common.h
drivers/infiniband/hw/hfi1/verbs.c

index 3e27794ec750c33cfab3c386535e8e6c64137681..7108d4d9225920c25443806a93654d2709fadd6b 100644 (file)
@@ -328,6 +328,7 @@ struct diag_pkt {
 #define SC15_PACKET 0xF
 #define SIZE_OF_CRC 1
 #define SIZE_OF_LT 1
+#define MAX_16B_PADDING 12 /* CRC = 4, LT = 1, Pad = 0 to 7 bytes */
 
 #define LIM_MGMT_P_KEY       0x7FFF
 #define FULL_MGMT_P_KEY      0xFFFF
index e232f3c608b41795a2da43b5439687756c9ec24d..726c064b22d8e779f742970858ed3676258c2621 100644 (file)
@@ -146,6 +146,9 @@ static int pio_wait(struct rvt_qp *qp,
 /* Length of buffer to create verbs txreq cache name */
 #define TXREQ_NAME_LEN 24
 
+/* 16B trailing buffer */
+static const u8 trail_buf[MAX_16B_PADDING];
+
 static uint wss_threshold;
 module_param(wss_threshold, uint, S_IRUGO);
 MODULE_PARM_DESC(wss_threshold, "Percentage (1-100) of LLC to use as a threshold for a cacheless copy");
@@ -814,7 +817,6 @@ static int build_verbs_tx_desc(
        u16 hdrbytes = tx->hdr_dwords << 2;
        u32 *hdr;
        u8 extra_bytes = 0;
-       static char trail_buf[12]; /* CRC = 4, LT = 1, Pad = 0 to 7 bytes */
 
        if (tx->phdr.hdr.hdr_type) {
                /*
@@ -869,9 +871,9 @@ static int build_verbs_tx_desc(
        }
 
        /* add icrc, lt byte, and padding to flit */
-       if (extra_bytes != 0)
+       if (extra_bytes)
                ret = sdma_txadd_kvaddr(sde->dd, &tx->txreq,
-                                       trail_buf, extra_bytes);
+                                       (void *)trail_buf, extra_bytes);
 
 bail_txadd:
        return ret;
@@ -1128,18 +1130,10 @@ int hfi1_verbs_send_pio(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
                                len -= slen;
                        }
                }
-               /*
-                * Bypass packet will need to copy additional
-                * bytes to accommodate for CRC and LT bytes
-                */
-               if (extra_bytes) {
-                       u8 *empty_buf;
+               /* add icrc, lt byte, and padding to flit */
+               if (extra_bytes)
+                       seg_pio_copy_mid(pbuf, trail_buf, extra_bytes);
 
-                       empty_buf = kcalloc(extra_bytes, sizeof(u8),
-                                           GFP_KERNEL);
-                       seg_pio_copy_mid(pbuf, empty_buf, extra_bytes);
-                       kfree(empty_buf);
-               }
                seg_pio_copy_end(pbuf);
        }