diff options
author | Dave Lim <dlim@nvidia.com> | 2016-05-10 14:08:55 -0400 |
---|---|---|
committer | Ashutosh Jha <ajha@nvidia.com> | 2016-05-10 21:10:45 -0400 |
commit | 558fa62396b2477eb7414e03571c062b9dfc3fe1 (patch) | |
tree | d1d180f78fe2faac4e781e6b12a182a947ec47d3 /drivers/net | |
parent | 4ad7aab2aba4ac345da3cbd79c6c48c0be4e8736 (diff) |
net: eqos: Fix race condition with rx own bit.
Resolved race condition where there could be dma
outstanding for same rx descriptor which has own
bit set to zero.
Bug 1762280
Change-Id: I53a9361037d1783b030db78ddd249295b61651e1
Signed-off-by: Dave Lim <dlim@nvidia.com>
Reviewed-on: http://git-master/r/1144836
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Ajay Gupta <ajayg@nvidia.com>
Reviewed-by: Anirban Ray <aray@nvidia.com>
Reviewed-by: Ashutosh Jha <ajha@nvidia.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ethernet/nvidia/eqos/dev.c | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/nvidia/eqos/drv.c | 19 | ||||
-rw-r--r-- | drivers/net/ethernet/nvidia/eqos/yheader.h | 4 |
3 files changed, 24 insertions, 4 deletions
diff --git a/drivers/net/ethernet/nvidia/eqos/dev.c b/drivers/net/ethernet/nvidia/eqos/dev.c index 41cb8dad1..16aabbc90 100644 --- a/drivers/net/ethernet/nvidia/eqos/dev.c +++ b/drivers/net/ethernet/nvidia/eqos/dev.c | |||
@@ -29,7 +29,7 @@ | |||
29 | * DAMAGE. | 29 | * DAMAGE. |
30 | * ========================================================================= */ | 30 | * ========================================================================= */ |
31 | /* | 31 | /* |
32 | * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. | 32 | * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. |
33 | * | 33 | * |
34 | * This program is free software; you can redistribute it and/or modify it | 34 | * This program is free software; you can redistribute it and/or modify it |
35 | * under the terms and conditions of the GNU General Public License, | 35 | * under the terms and conditions of the GNU General Public License, |
@@ -2869,6 +2869,9 @@ static void rx_descriptor_init(struct eqos_prv_data *pdata, UINT qinx) | |||
2869 | /* update the starting address of desc chain/ring */ | 2869 | /* update the starting address of desc chain/ring */ |
2870 | DMA_RDLAR_WR(qinx, GET_RX_DESC_DMA_ADDR(qinx, start_index)); | 2870 | DMA_RDLAR_WR(qinx, GET_RX_DESC_DMA_ADDR(qinx, start_index)); |
2871 | 2871 | ||
2872 | prx_ring->hw_last_rx_desc_addr = | ||
2873 | GET_RX_DESC_DMA_ADDR(qinx, start_index); | ||
2874 | |||
2872 | DBGPR("<--rx_descriptor_init\n"); | 2875 | DBGPR("<--rx_descriptor_init\n"); |
2873 | } | 2876 | } |
2874 | 2877 | ||
diff --git a/drivers/net/ethernet/nvidia/eqos/drv.c b/drivers/net/ethernet/nvidia/eqos/drv.c index 617027371..2c56f3bda 100644 --- a/drivers/net/ethernet/nvidia/eqos/drv.c +++ b/drivers/net/ethernet/nvidia/eqos/drv.c | |||
@@ -29,7 +29,7 @@ | |||
29 | * DAMAGE. | 29 | * DAMAGE. |
30 | * ========================================================================= */ | 30 | * ========================================================================= */ |
31 | /* | 31 | /* |
32 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | 32 | * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. |
33 | * | 33 | * |
34 | * This program is free software; you can redistribute it and/or modify it | 34 | * This program is free software; you can redistribute it and/or modify it |
35 | * under the terms and conditions of the GNU General Public License, | 35 | * under the terms and conditions of the GNU General Public License, |
@@ -2338,18 +2338,33 @@ static int process_rx_completions(struct eqos_prv_data *pdata, | |||
2338 | struct s_rx_desc *prx_desc = NULL; | 2338 | struct s_rx_desc *prx_desc = NULL; |
2339 | UINT pkt_len; | 2339 | UINT pkt_len; |
2340 | UINT err_bits = EQOS_RDESC3_ES_BITS; | 2340 | UINT err_bits = EQOS_RDESC3_ES_BITS; |
2341 | u32 sw_cur_rx_desc_addr = 0; | ||
2342 | u32 hw_cur_rx_desc_addr = 0; | ||
2341 | 2343 | ||
2342 | int ret; | 2344 | int ret; |
2343 | 2345 | ||
2344 | DBGPR("-->%s(): qinx = %u, quota = %d\n", __func__, qinx, quota); | 2346 | DBGPR("-->%s(): qinx = %u, quota = %d\n", __func__, qinx, quota); |
2345 | 2347 | ||
2348 | hw_cur_rx_desc_addr = prx_ring->hw_last_rx_desc_addr; | ||
2346 | while (received < quota) { | 2349 | while (received < quota) { |
2347 | prx_swcx_desc = GET_RX_BUF_PTR(qinx, prx_ring->cur_rx); | 2350 | prx_swcx_desc = GET_RX_BUF_PTR(qinx, prx_ring->cur_rx); |
2348 | prx_desc = GET_RX_DESC_PTR(qinx, prx_ring->cur_rx); | 2351 | prx_desc = GET_RX_DESC_PTR(qinx, prx_ring->cur_rx); |
2349 | 2352 | ||
2353 | sw_cur_rx_desc_addr = | ||
2354 | GET_RX_DESC_DMA_ADDR(qinx, prx_ring->cur_rx); | ||
2355 | |||
2350 | /* check for data availability */ | 2356 | /* check for data availability */ |
2351 | if (!(prx_desc->rdes3 & EQOS_RDESC3_OWN) && | 2357 | if (!(prx_desc->rdes3 & EQOS_RDESC3_OWN) && |
2352 | prx_swcx_desc->skb) { | 2358 | prx_swcx_desc->skb) { |
2359 | if (hw_cur_rx_desc_addr == sw_cur_rx_desc_addr) { | ||
2360 | DMA_CHRDR_RD(qinx, | ||
2361 | prx_ring->hw_last_rx_desc_addr); | ||
2362 | if (prx_ring->hw_last_rx_desc_addr == | ||
2363 | hw_cur_rx_desc_addr) | ||
2364 | break; | ||
2365 | hw_cur_rx_desc_addr = | ||
2366 | prx_ring->hw_last_rx_desc_addr; | ||
2367 | } | ||
2353 | #ifdef EQOS_ENABLE_RX_DESC_DUMP | 2368 | #ifdef EQOS_ENABLE_RX_DESC_DUMP |
2354 | dump_rx_desc(qinx, prx_desc, prx_ring->cur_rx); | 2369 | dump_rx_desc(qinx, prx_desc, prx_ring->cur_rx); |
2355 | #endif | 2370 | #endif |
diff --git a/drivers/net/ethernet/nvidia/eqos/yheader.h b/drivers/net/ethernet/nvidia/eqos/yheader.h index 2e4e5b7e5..bc1cb7823 100644 --- a/drivers/net/ethernet/nvidia/eqos/yheader.h +++ b/drivers/net/ethernet/nvidia/eqos/yheader.h | |||
@@ -29,7 +29,7 @@ | |||
29 | * DAMAGE. | 29 | * DAMAGE. |
30 | * ========================================================================= */ | 30 | * ========================================================================= */ |
31 | /* | 31 | /* |
32 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | 32 | * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. |
33 | * | 33 | * |
34 | * This program is free software; you can redistribute it and/or modify it | 34 | * This program is free software; you can redistribute it and/or modify it |
35 | * under the terms and conditions of the GNU General Public License, | 35 | * under the terms and conditions of the GNU General Public License, |
@@ -1019,6 +1019,8 @@ struct rx_ring { | |||
1019 | /* for rx vlan stripping */ | 1019 | /* for rx vlan stripping */ |
1020 | u32 rx_inner_vlan_strip; | 1020 | u32 rx_inner_vlan_strip; |
1021 | u32 rx_outer_vlan_strip; | 1021 | u32 rx_outer_vlan_strip; |
1022 | |||
1023 | u32 hw_last_rx_desc_addr; | ||
1022 | }; | 1024 | }; |
1023 | 1025 | ||
1024 | struct eqos_rx_queue { | 1026 | struct eqos_rx_queue { |