IB/iser: Fix possible bogus DMA unmapping
authorSagi Grimberg <sagig@mellanox.com>
Thu, 6 Aug 2015 15:32:50 +0000 (18:32 +0300)
committerDoug Ledford <dledford@redhat.com>
Sun, 30 Aug 2015 22:12:28 +0000 (18:12 -0400)
If iser_initialize_task_headers() routine failed before
dma mapping, we should not attempt to unmap in cleanup_task().

Fixes: 7414dde0a6c3a958e (IB/iser: Fix race between iser connection ...)
Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/ulp/iser/iscsi_iser.c
drivers/infiniband/ulp/iser/iscsi_iser.h

index 9cc7319..169cc3e 100644 (file)
@@ -200,6 +200,7 @@ iser_initialize_task_headers(struct iscsi_task *task,
                goto out;
        }
 
+       tx_desc->mapped = true;
        tx_desc->dma_addr = dma_addr;
        tx_desc->tx_sg[0].addr   = tx_desc->dma_addr;
        tx_desc->tx_sg[0].length = ISER_HEADERS_LEN;
@@ -359,16 +360,19 @@ iscsi_iser_task_xmit(struct iscsi_task *task)
 static void iscsi_iser_cleanup_task(struct iscsi_task *task)
 {
        struct iscsi_iser_task *iser_task = task->dd_data;
-       struct iser_tx_desc    *tx_desc   = &iser_task->desc;
-       struct iser_conn       *iser_conn         = task->conn->dd_data;
+       struct iser_tx_desc *tx_desc = &iser_task->desc;
+       struct iser_conn *iser_conn = task->conn->dd_data;
        struct iser_device *device = iser_conn->ib_conn.device;
 
        /* DEVICE_REMOVAL event might have already released the device */
        if (!device)
                return;
 
-       ib_dma_unmap_single(device->ib_device,
-               tx_desc->dma_addr, ISER_HEADERS_LEN, DMA_TO_DEVICE);
+       if (likely(tx_desc->mapped)) {
+               ib_dma_unmap_single(device->ib_device, tx_desc->dma_addr,
+                                   ISER_HEADERS_LEN, DMA_TO_DEVICE);
+               tx_desc->mapped = false;
+       }
 
        /* mgmt tasks do not need special cleanup */
        if (!task->sc)
index 262ba1f..d2b6caf 100644 (file)
@@ -270,6 +270,7 @@ enum iser_desc_type {
  *                 sg[1] optionally points to either of immediate data
  *                 unsolicited data-out or control
  * @num_sge:       number sges used on this TX task
+ * @mapped:        Is the task header mapped
  */
 struct iser_tx_desc {
        struct iser_hdr              iser_header;
@@ -278,6 +279,7 @@ struct iser_tx_desc {
        u64                          dma_addr;
        struct ib_sge                tx_sg[2];
        int                          num_sge;
+       bool                         mapped;
 };
 
 #define ISER_RX_PAD_SIZE       (256 - (ISER_RX_PAYLOAD_SIZE + \