IB/mad: Check and handle potential DMA mapping errors
authorYan Burman <yanb@mellanox.com>
Tue, 11 Mar 2014 12:41:47 +0000 (14:41 +0200)
committerRoland Dreier <roland@purestorage.com>
Tue, 1 Apr 2014 17:36:07 +0000 (10:36 -0700)
Running with DMA_API_DEBUG enabled and not checking for DMA mapping
errors triggers a kernel stack trace with "DMA-API: device driver
failed to check map error" message.  Add these checks to the MAD
module, both to be be more robust and also eliminate these
false-positive stack traces.

Signed-off-by: Yan Burman <yanb@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
drivers/infiniband/core/mad.c

index 4c837e66516b894f88f689d93c9a84c501fa6b47..ab31f136d04b00a322a5e31f5c715deae9f09b4b 100644 (file)
@@ -1022,12 +1022,21 @@ int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr)
                                        mad_send_wr->send_buf.mad,
                                        sge[0].length,
                                        DMA_TO_DEVICE);
+       if (unlikely(ib_dma_mapping_error(mad_agent->device, sge[0].addr)))
+               return -ENOMEM;
+
        mad_send_wr->header_mapping = sge[0].addr;
 
        sge[1].addr = ib_dma_map_single(mad_agent->device,
                                        ib_get_payload(mad_send_wr),
                                        sge[1].length,
                                        DMA_TO_DEVICE);
+       if (unlikely(ib_dma_mapping_error(mad_agent->device, sge[1].addr))) {
+               ib_dma_unmap_single(mad_agent->device,
+                                   mad_send_wr->header_mapping,
+                                   sge[0].length, DMA_TO_DEVICE);
+               return -ENOMEM;
+       }
        mad_send_wr->payload_mapping = sge[1].addr;
 
        spin_lock_irqsave(&qp_info->send_queue.lock, flags);
@@ -2590,6 +2599,11 @@ static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info,
                                                 sizeof *mad_priv -
                                                   sizeof mad_priv->header,
                                                 DMA_FROM_DEVICE);
+               if (unlikely(ib_dma_mapping_error(qp_info->port_priv->device,
+                                                 sg_list.addr))) {
+                       ret = -ENOMEM;
+                       break;
+               }
                mad_priv->header.mapping = sg_list.addr;
                recv_wr.wr_id = (unsigned long)&mad_priv->header.mad_list;
                mad_priv->header.mad_list.mad_queue = recv_queue;