diff options
author | Eli Cohen <eli@dev.mellanox.co.il> | 2013-10-23 02:53:18 -0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2013-11-08 17:43:00 -0500 |
commit | 952f5f6e807ba82e1b82fcfcf7f73db022342aa7 (patch) | |
tree | 75651d8c239a0957981a7e395c0d155d4cc89d45 /drivers/net/ethernet | |
parent | cfd8f1d49b61b20aab77d5af5ec907dc99bb0064 (diff) |
mlx5: Fix cleanup flow when DMA mapping fails
If DMA mapping fails, the driver cleared the object that holds the
previously DMA mapped pages. Fix this by allocating a new object for
the command that reports back to firmware that pages can't be
supplied.
Signed-off-by: Eli Cohen <eli@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c index 7b12acf210f8..a0d0da35578c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c | |||
@@ -181,6 +181,7 @@ static int give_pages(struct mlx5_core_dev *dev, u16 func_id, int npages, | |||
181 | { | 181 | { |
182 | struct mlx5_manage_pages_inbox *in; | 182 | struct mlx5_manage_pages_inbox *in; |
183 | struct mlx5_manage_pages_outbox out; | 183 | struct mlx5_manage_pages_outbox out; |
184 | struct mlx5_manage_pages_inbox *nin; | ||
184 | struct page *page; | 185 | struct page *page; |
185 | int inlen; | 186 | int inlen; |
186 | u64 addr; | 187 | u64 addr; |
@@ -247,13 +248,20 @@ static int give_pages(struct mlx5_core_dev *dev, u16 func_id, int npages, | |||
247 | 248 | ||
248 | out_alloc: | 249 | out_alloc: |
249 | if (notify_fail) { | 250 | if (notify_fail) { |
250 | memset(in, 0, inlen); | 251 | nin = kzalloc(sizeof(*nin), GFP_KERNEL); |
252 | if (!nin) { | ||
253 | mlx5_core_warn(dev, "allocation failed\n"); | ||
254 | goto unmap; | ||
255 | } | ||
251 | memset(&out, 0, sizeof(out)); | 256 | memset(&out, 0, sizeof(out)); |
252 | in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_MANAGE_PAGES); | 257 | nin->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_MANAGE_PAGES); |
253 | in->hdr.opmod = cpu_to_be16(MLX5_PAGES_CANT_GIVE); | 258 | nin->hdr.opmod = cpu_to_be16(MLX5_PAGES_CANT_GIVE); |
254 | if (mlx5_cmd_exec(dev, in, sizeof(*in), &out, sizeof(out))) | 259 | if (mlx5_cmd_exec(dev, nin, sizeof(*nin), &out, sizeof(out))) |
255 | mlx5_core_warn(dev, "\n"); | 260 | mlx5_core_warn(dev, "page notify failed\n"); |
261 | kfree(nin); | ||
256 | } | 262 | } |
263 | |||
264 | unmap: | ||
257 | for (i--; i >= 0; i--) { | 265 | for (i--; i >= 0; i--) { |
258 | addr = be64_to_cpu(in->pas[i]); | 266 | addr = be64_to_cpu(in->pas[i]); |
259 | page = remove_page(dev, addr); | 267 | page = remove_page(dev, addr); |