ipq40xx: essedma: Add fix for memory allocation issues
This patch adds a ChromiumOS 3.18 patch [0] that fixes memory
allocation issues under memory pressure by keeping track
of missed allocs and rectify the omission at a later date.
It also adds ethtool counters for memory allocation
failures accounting so this can be verified.
[0] <d4e1e4ce68>
Reported-by: Chen Minqiang <ptpt52@gmail.com>
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
			
			
This commit is contained in:
		| @@ -0,0 +1,197 @@ | |||||||
|  | From 72c050acbc425ef99313d5c2e4c866e25567e569 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Rakesh Nair <ranair@codeaurora.org> | ||||||
|  | Date: Thu, 8 Jun 2017 14:29:20 +0530 | ||||||
|  | Subject: [PATCH] CHROMIUM: net: qualcomm: Add fix for memory allocation issues | ||||||
|  |  | ||||||
|  | Added ethtool counters for memory allocation failures accounting. | ||||||
|  | Added support to track number of allocation failures that could | ||||||
|  | not be fulfilled in the current iteration in the rx descriptor | ||||||
|  | field and use the info to allocate in the subsequent iteration. | ||||||
|  |  | ||||||
|  | Change-Id: Ie4fd3b6cf25304e5db2c9247a498791e7e9bb4aa | ||||||
|  | Signed-off-by: Rakesh Nair <ranair@codeaurora.org> | ||||||
|  | Signed-off-by: Kan Yan <kyan@google.com> | ||||||
|  | Reviewed-on: https://chromium-review.googlesource.com/535419 | ||||||
|  | Reviewed-by: Grant Grundler <grundler@chromium.org> | ||||||
|  | --- | ||||||
|  |  drivers/net/ethernet/qualcomm/essedma/edma.c  | 54 ++++++++++++++----- | ||||||
|  |  drivers/net/ethernet/qualcomm/essedma/edma.h  |  2 + | ||||||
|  |  .../ethernet/qualcomm/essedma/edma_ethtool.c  |  1 + | ||||||
|  |  3 files changed, 43 insertions(+), 14 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/ethernet/qualcomm/essedma/edma.c | ||||||
|  | +++ b/drivers/net/ethernet/qualcomm/essedma/edma.c | ||||||
|  | @@ -103,6 +103,9 @@ static int edma_alloc_rx_ring(struct edm | ||||||
|  |  		return -ENOMEM; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	/* Initialize pending_fill */ | ||||||
|  | +	erxd->pending_fill = 0; | ||||||
|  | + | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -185,11 +188,8 @@ static int edma_alloc_rx_buf(struct edma | ||||||
|  |  	u16 prod_idx, length; | ||||||
|  |  	u32 reg_data; | ||||||
|  |   | ||||||
|  | -	if (cleaned_count > erdr->count) { | ||||||
|  | -		dev_err(&pdev->dev, "Incorrect cleaned_count %d", | ||||||
|  | -		       cleaned_count); | ||||||
|  | -		return -1; | ||||||
|  | -	} | ||||||
|  | +	if (cleaned_count > erdr->count) | ||||||
|  | +		cleaned_count = erdr->count - 1; | ||||||
|  |   | ||||||
|  |  	i = erdr->sw_next_to_fill; | ||||||
|  |   | ||||||
|  | @@ -199,6 +199,9 @@ static int edma_alloc_rx_buf(struct edma | ||||||
|  |   | ||||||
|  |  		if (sw_desc->flags & EDMA_SW_DESC_FLAG_SKB_REUSE) { | ||||||
|  |  			skb = sw_desc->skb; | ||||||
|  | + | ||||||
|  | +			/* Clear REUSE Flag */ | ||||||
|  | +			sw_desc->flags &= ~EDMA_SW_DESC_FLAG_SKB_REUSE; | ||||||
|  |  		} else { | ||||||
|  |  			/* alloc skb */ | ||||||
|  |  			skb = netdev_alloc_skb_ip_align(edma_netdev[0], length); | ||||||
|  | @@ -264,6 +267,13 @@ static int edma_alloc_rx_buf(struct edma | ||||||
|  |  	reg_data &= ~EDMA_RFD_PROD_IDX_BITS; | ||||||
|  |  	reg_data |= prod_idx; | ||||||
|  |  	edma_write_reg(EDMA_REG_RFD_IDX_Q(queue_id), reg_data); | ||||||
|  | + | ||||||
|  | +	/* If we couldn't allocate all the buffers | ||||||
|  | +	 * we increment the alloc failure counters | ||||||
|  | +	 */ | ||||||
|  | +	if (cleaned_count) | ||||||
|  | +		edma_cinfo->edma_ethstats.rx_alloc_fail_ctr++; | ||||||
|  | + | ||||||
|  |  	return cleaned_count; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -534,7 +544,7 @@ static int edma_rx_complete_paged(struct | ||||||
|  |   * edma_rx_complete() | ||||||
|  |   *	Main api called from the poll function to process rx packets. | ||||||
|  |   */ | ||||||
|  | -static void edma_rx_complete(struct edma_common_info *edma_cinfo, | ||||||
|  | +static u16 edma_rx_complete(struct edma_common_info *edma_cinfo, | ||||||
|  |  			    int *work_done, int work_to_do, int queue_id, | ||||||
|  |  			    struct napi_struct *napi) | ||||||
|  |  { | ||||||
|  | @@ -554,6 +564,7 @@ static void edma_rx_complete(struct edma | ||||||
|  |  	u16 count = erdr->count, rfd_avail; | ||||||
|  |  	u8 queue_to_rxid[8] = {0, 0, 1, 1, 2, 2, 3, 3}; | ||||||
|  |   | ||||||
|  | +	cleaned_count = erdr->pending_fill; | ||||||
|  |  	sw_next_to_clean = erdr->sw_next_to_clean; | ||||||
|  |   | ||||||
|  |  	edma_read_reg(EDMA_REG_RFD_IDX_Q(queue_id), &data); | ||||||
|  | @@ -652,12 +663,13 @@ static void edma_rx_complete(struct edma | ||||||
|  |  						(*work_done)++; | ||||||
|  |  						drop_count = 0; | ||||||
|  |  					} | ||||||
|  | -					if (cleaned_count == EDMA_RX_BUFFER_WRITE) { | ||||||
|  | +					if (cleaned_count >= EDMA_RX_BUFFER_WRITE) { | ||||||
|  |  						/* If buffer clean count reaches 16, we replenish HW buffers. */ | ||||||
|  |  						ret_count = edma_alloc_rx_buf(edma_cinfo, erdr, cleaned_count, queue_id); | ||||||
|  |  						edma_write_reg(EDMA_REG_RX_SW_CONS_IDX_Q(queue_id), | ||||||
|  |  							      sw_next_to_clean); | ||||||
|  |  						cleaned_count = ret_count; | ||||||
|  | +						erdr->pending_fill = ret_count; | ||||||
|  |  					} | ||||||
|  |  					continue; | ||||||
|  |  				} | ||||||
|  | @@ -730,11 +742,12 @@ static void edma_rx_complete(struct edma | ||||||
|  |  			adapter->stats.rx_bytes += length; | ||||||
|  |   | ||||||
|  |  			/* Check if we reached refill threshold */ | ||||||
|  | -			if (cleaned_count == EDMA_RX_BUFFER_WRITE) { | ||||||
|  | +			if (cleaned_count >= EDMA_RX_BUFFER_WRITE) { | ||||||
|  |  				ret_count = edma_alloc_rx_buf(edma_cinfo, erdr, cleaned_count, queue_id); | ||||||
|  |  				edma_write_reg(EDMA_REG_RX_SW_CONS_IDX_Q(queue_id), | ||||||
|  |  					      sw_next_to_clean); | ||||||
|  |  				cleaned_count = ret_count; | ||||||
|  | +				erdr->pending_fill = ret_count; | ||||||
|  |  			} | ||||||
|  |   | ||||||
|  |  			/* At this point skb should go to stack */ | ||||||
|  | @@ -756,11 +769,17 @@ static void edma_rx_complete(struct edma | ||||||
|  |  	/* Refill here in case refill threshold wasn't reached */ | ||||||
|  |  	if (likely(cleaned_count)) { | ||||||
|  |  		ret_count = edma_alloc_rx_buf(edma_cinfo, erdr, cleaned_count, queue_id); | ||||||
|  | -		if (ret_count) | ||||||
|  | -			dev_dbg(&pdev->dev, "Not all buffers was reallocated"); | ||||||
|  | +		erdr->pending_fill = ret_count; | ||||||
|  | +		if (ret_count) { | ||||||
|  | +			if (net_ratelimit()) | ||||||
|  | +				dev_dbg(&pdev->dev, "Not all buffers was reallocated"); | ||||||
|  | +		} | ||||||
|  | + | ||||||
|  |  		edma_write_reg(EDMA_REG_RX_SW_CONS_IDX_Q(queue_id), | ||||||
|  |  			      erdr->sw_next_to_clean); | ||||||
|  |  	} | ||||||
|  | + | ||||||
|  | +	return erdr->pending_fill; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  /* edma_delete_rfs_filter() | ||||||
|  | @@ -2064,6 +2083,7 @@ int edma_poll(struct napi_struct *napi, | ||||||
|  |  	u32 shadow_rx_status, shadow_tx_status; | ||||||
|  |  	int queue_id; | ||||||
|  |  	int i, work_done = 0; | ||||||
|  | +	u16 rx_pending_fill; | ||||||
|  |   | ||||||
|  |  	/* Store the Rx/Tx status by ANDing it with | ||||||
|  |  	 * appropriate CPU RX?TX mask | ||||||
|  | @@ -2097,13 +2117,19 @@ int edma_poll(struct napi_struct *napi, | ||||||
|  |  	 */ | ||||||
|  |  	while (edma_percpu_info->rx_status) { | ||||||
|  |  		queue_id = ffs(edma_percpu_info->rx_status) - 1; | ||||||
|  | -		edma_rx_complete(edma_cinfo, &work_done, | ||||||
|  | -			        budget, queue_id, napi); | ||||||
|  | +		rx_pending_fill = edma_rx_complete(edma_cinfo, &work_done, | ||||||
|  | +						   budget, queue_id, napi); | ||||||
|  |   | ||||||
|  | -		if (likely(work_done < budget)) | ||||||
|  | +		if (likely(work_done < budget)) { | ||||||
|  | +			if (rx_pending_fill) { | ||||||
|  | +                          	/* reschedule poll() to refill rx buffer deficit */ | ||||||
|  | +				work_done = budget; | ||||||
|  | +				break; | ||||||
|  | +			} | ||||||
|  |  			edma_percpu_info->rx_status &= ~(1 << queue_id); | ||||||
|  | -		else | ||||||
|  | +		} else { | ||||||
|  |  			break; | ||||||
|  | +		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	/* Clear the status register, to avoid the interrupts to | ||||||
|  | --- a/drivers/net/ethernet/qualcomm/essedma/edma.h | ||||||
|  | +++ b/drivers/net/ethernet/qualcomm/essedma/edma.h | ||||||
|  | @@ -225,6 +225,7 @@ struct edma_ethtool_statistics { | ||||||
|  |  	u32 rx_q6_byte; | ||||||
|  |  	u32 rx_q7_byte; | ||||||
|  |  	u32 tx_desc_error; | ||||||
|  | +	u32 rx_alloc_fail_ctr; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  struct edma_mdio_data { | ||||||
|  | @@ -362,6 +363,7 @@ struct edma_rfd_desc_ring { | ||||||
|  |  	dma_addr_t dma; /* descriptor ring physical address */ | ||||||
|  |  	u16 sw_next_to_fill; /* next descriptor to fill */ | ||||||
|  |  	u16 sw_next_to_clean; /* next descriptor to clean */ | ||||||
|  | +	u16 pending_fill; /* fill pending from previous iteration */ | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  /* edma_rfs_flter_node - rfs filter node in hash table */ | ||||||
|  | --- a/drivers/net/ethernet/qualcomm/essedma/edma_ethtool.c | ||||||
|  | +++ b/drivers/net/ethernet/qualcomm/essedma/edma_ethtool.c | ||||||
|  | @@ -78,6 +78,7 @@ static const struct edma_ethtool_stats e | ||||||
|  |  	{"rx_q6_byte", EDMA_STAT(rx_q6_byte)}, | ||||||
|  |  	{"rx_q7_byte", EDMA_STAT(rx_q7_byte)}, | ||||||
|  |  	{"tx_desc_error", EDMA_STAT(tx_desc_error)}, | ||||||
|  | +	{"rx_alloc_fail_ctr", EDMA_STAT(rx_alloc_fail_ctr)}, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  #define EDMA_STATS_LEN ARRAY_SIZE(edma_gstrings_stats) | ||||||
| @@ -0,0 +1,197 @@ | |||||||
|  | From 72c050acbc425ef99313d5c2e4c866e25567e569 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Rakesh Nair <ranair@codeaurora.org> | ||||||
|  | Date: Thu, 8 Jun 2017 14:29:20 +0530 | ||||||
|  | Subject: [PATCH] CHROMIUM: net: qualcomm: Add fix for memory allocation issues | ||||||
|  |  | ||||||
|  | Added ethtool counters for memory allocation failures accounting. | ||||||
|  | Added support to track number of allocation failures that could | ||||||
|  | not be fulfilled in the current iteration in the rx descriptor | ||||||
|  | field and use the info to allocate in the subsequent iteration. | ||||||
|  |  | ||||||
|  | Change-Id: Ie4fd3b6cf25304e5db2c9247a498791e7e9bb4aa | ||||||
|  | Signed-off-by: Rakesh Nair <ranair@codeaurora.org> | ||||||
|  | Signed-off-by: Kan Yan <kyan@google.com> | ||||||
|  | Reviewed-on: https://chromium-review.googlesource.com/535419 | ||||||
|  | Reviewed-by: Grant Grundler <grundler@chromium.org> | ||||||
|  | --- | ||||||
|  |  drivers/net/ethernet/qualcomm/essedma/edma.c  | 54 ++++++++++++++----- | ||||||
|  |  drivers/net/ethernet/qualcomm/essedma/edma.h  |  2 + | ||||||
|  |  .../ethernet/qualcomm/essedma/edma_ethtool.c  |  1 + | ||||||
|  |  3 files changed, 43 insertions(+), 14 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/ethernet/qualcomm/essedma/edma.c | ||||||
|  | +++ b/drivers/net/ethernet/qualcomm/essedma/edma.c | ||||||
|  | @@ -103,6 +103,9 @@ static int edma_alloc_rx_ring(struct edm | ||||||
|  |  		return -ENOMEM; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	/* Initialize pending_fill */ | ||||||
|  | +	erxd->pending_fill = 0; | ||||||
|  | + | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -185,11 +188,8 @@ static int edma_alloc_rx_buf(struct edma | ||||||
|  |  	u16 prod_idx, length; | ||||||
|  |  	u32 reg_data; | ||||||
|  |   | ||||||
|  | -	if (cleaned_count > erdr->count) { | ||||||
|  | -		dev_err(&pdev->dev, "Incorrect cleaned_count %d", | ||||||
|  | -		       cleaned_count); | ||||||
|  | -		return -1; | ||||||
|  | -	} | ||||||
|  | +	if (cleaned_count > erdr->count) | ||||||
|  | +		cleaned_count = erdr->count - 1; | ||||||
|  |   | ||||||
|  |  	i = erdr->sw_next_to_fill; | ||||||
|  |   | ||||||
|  | @@ -199,6 +199,9 @@ static int edma_alloc_rx_buf(struct edma | ||||||
|  |   | ||||||
|  |  		if (sw_desc->flags & EDMA_SW_DESC_FLAG_SKB_REUSE) { | ||||||
|  |  			skb = sw_desc->skb; | ||||||
|  | + | ||||||
|  | +			/* Clear REUSE Flag */ | ||||||
|  | +			sw_desc->flags &= ~EDMA_SW_DESC_FLAG_SKB_REUSE; | ||||||
|  |  		} else { | ||||||
|  |  			/* alloc skb */ | ||||||
|  |  			skb = netdev_alloc_skb_ip_align(edma_netdev[0], length); | ||||||
|  | @@ -264,6 +267,13 @@ static int edma_alloc_rx_buf(struct edma | ||||||
|  |  	reg_data &= ~EDMA_RFD_PROD_IDX_BITS; | ||||||
|  |  	reg_data |= prod_idx; | ||||||
|  |  	edma_write_reg(EDMA_REG_RFD_IDX_Q(queue_id), reg_data); | ||||||
|  | + | ||||||
|  | +	/* If we couldn't allocate all the buffers | ||||||
|  | +	 * we increment the alloc failure counters | ||||||
|  | +	 */ | ||||||
|  | +	if (cleaned_count) | ||||||
|  | +		edma_cinfo->edma_ethstats.rx_alloc_fail_ctr++; | ||||||
|  | + | ||||||
|  |  	return cleaned_count; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -534,7 +544,7 @@ static int edma_rx_complete_paged(struct | ||||||
|  |   * edma_rx_complete() | ||||||
|  |   *	Main api called from the poll function to process rx packets. | ||||||
|  |   */ | ||||||
|  | -static void edma_rx_complete(struct edma_common_info *edma_cinfo, | ||||||
|  | +static u16 edma_rx_complete(struct edma_common_info *edma_cinfo, | ||||||
|  |  			    int *work_done, int work_to_do, int queue_id, | ||||||
|  |  			    struct napi_struct *napi) | ||||||
|  |  { | ||||||
|  | @@ -554,6 +564,7 @@ static void edma_rx_complete(struct edma | ||||||
|  |  	u16 count = erdr->count, rfd_avail; | ||||||
|  |  	u8 queue_to_rxid[8] = {0, 0, 1, 1, 2, 2, 3, 3}; | ||||||
|  |   | ||||||
|  | +	cleaned_count = erdr->pending_fill; | ||||||
|  |  	sw_next_to_clean = erdr->sw_next_to_clean; | ||||||
|  |   | ||||||
|  |  	edma_read_reg(EDMA_REG_RFD_IDX_Q(queue_id), &data); | ||||||
|  | @@ -652,12 +663,13 @@ static void edma_rx_complete(struct edma | ||||||
|  |  						(*work_done)++; | ||||||
|  |  						drop_count = 0; | ||||||
|  |  					} | ||||||
|  | -					if (cleaned_count == EDMA_RX_BUFFER_WRITE) { | ||||||
|  | +					if (cleaned_count >= EDMA_RX_BUFFER_WRITE) { | ||||||
|  |  						/* If buffer clean count reaches 16, we replenish HW buffers. */ | ||||||
|  |  						ret_count = edma_alloc_rx_buf(edma_cinfo, erdr, cleaned_count, queue_id); | ||||||
|  |  						edma_write_reg(EDMA_REG_RX_SW_CONS_IDX_Q(queue_id), | ||||||
|  |  							      sw_next_to_clean); | ||||||
|  |  						cleaned_count = ret_count; | ||||||
|  | +						erdr->pending_fill = ret_count; | ||||||
|  |  					} | ||||||
|  |  					continue; | ||||||
|  |  				} | ||||||
|  | @@ -730,11 +742,12 @@ static void edma_rx_complete(struct edma | ||||||
|  |  			adapter->stats.rx_bytes += length; | ||||||
|  |   | ||||||
|  |  			/* Check if we reached refill threshold */ | ||||||
|  | -			if (cleaned_count == EDMA_RX_BUFFER_WRITE) { | ||||||
|  | +			if (cleaned_count >= EDMA_RX_BUFFER_WRITE) { | ||||||
|  |  				ret_count = edma_alloc_rx_buf(edma_cinfo, erdr, cleaned_count, queue_id); | ||||||
|  |  				edma_write_reg(EDMA_REG_RX_SW_CONS_IDX_Q(queue_id), | ||||||
|  |  					      sw_next_to_clean); | ||||||
|  |  				cleaned_count = ret_count; | ||||||
|  | +				erdr->pending_fill = ret_count; | ||||||
|  |  			} | ||||||
|  |   | ||||||
|  |  			/* At this point skb should go to stack */ | ||||||
|  | @@ -756,11 +769,17 @@ static void edma_rx_complete(struct edma | ||||||
|  |  	/* Refill here in case refill threshold wasn't reached */ | ||||||
|  |  	if (likely(cleaned_count)) { | ||||||
|  |  		ret_count = edma_alloc_rx_buf(edma_cinfo, erdr, cleaned_count, queue_id); | ||||||
|  | -		if (ret_count) | ||||||
|  | -			dev_dbg(&pdev->dev, "Not all buffers was reallocated"); | ||||||
|  | +		erdr->pending_fill = ret_count; | ||||||
|  | +		if (ret_count) { | ||||||
|  | +			if (net_ratelimit()) | ||||||
|  | +				dev_dbg(&pdev->dev, "Not all buffers was reallocated"); | ||||||
|  | +		} | ||||||
|  | + | ||||||
|  |  		edma_write_reg(EDMA_REG_RX_SW_CONS_IDX_Q(queue_id), | ||||||
|  |  			      erdr->sw_next_to_clean); | ||||||
|  |  	} | ||||||
|  | + | ||||||
|  | +	return erdr->pending_fill; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  /* edma_delete_rfs_filter() | ||||||
|  | @@ -2064,6 +2083,7 @@ int edma_poll(struct napi_struct *napi, | ||||||
|  |  	u32 shadow_rx_status, shadow_tx_status; | ||||||
|  |  	int queue_id; | ||||||
|  |  	int i, work_done = 0; | ||||||
|  | +	u16 rx_pending_fill; | ||||||
|  |   | ||||||
|  |  	/* Store the Rx/Tx status by ANDing it with | ||||||
|  |  	 * appropriate CPU RX?TX mask | ||||||
|  | @@ -2097,13 +2117,19 @@ int edma_poll(struct napi_struct *napi, | ||||||
|  |  	 */ | ||||||
|  |  	while (edma_percpu_info->rx_status) { | ||||||
|  |  		queue_id = ffs(edma_percpu_info->rx_status) - 1; | ||||||
|  | -		edma_rx_complete(edma_cinfo, &work_done, | ||||||
|  | -			        budget, queue_id, napi); | ||||||
|  | +		rx_pending_fill = edma_rx_complete(edma_cinfo, &work_done, | ||||||
|  | +						   budget, queue_id, napi); | ||||||
|  |   | ||||||
|  | -		if (likely(work_done < budget)) | ||||||
|  | +		if (likely(work_done < budget)) { | ||||||
|  | +			if (rx_pending_fill) { | ||||||
|  | +                          	/* reschedule poll() to refill rx buffer deficit */ | ||||||
|  | +				work_done = budget; | ||||||
|  | +				break; | ||||||
|  | +			} | ||||||
|  |  			edma_percpu_info->rx_status &= ~(1 << queue_id); | ||||||
|  | -		else | ||||||
|  | +		} else { | ||||||
|  |  			break; | ||||||
|  | +		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	/* Clear the status register, to avoid the interrupts to | ||||||
|  | --- a/drivers/net/ethernet/qualcomm/essedma/edma.h | ||||||
|  | +++ b/drivers/net/ethernet/qualcomm/essedma/edma.h | ||||||
|  | @@ -225,6 +225,7 @@ struct edma_ethtool_statistics { | ||||||
|  |  	u32 rx_q6_byte; | ||||||
|  |  	u32 rx_q7_byte; | ||||||
|  |  	u32 tx_desc_error; | ||||||
|  | +	u32 rx_alloc_fail_ctr; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  struct edma_mdio_data { | ||||||
|  | @@ -362,6 +363,7 @@ struct edma_rfd_desc_ring { | ||||||
|  |  	dma_addr_t dma; /* descriptor ring physical address */ | ||||||
|  |  	u16 sw_next_to_fill; /* next descriptor to fill */ | ||||||
|  |  	u16 sw_next_to_clean; /* next descriptor to clean */ | ||||||
|  | +	u16 pending_fill; /* fill pending from previous iteration */ | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  /* edma_rfs_flter_node - rfs filter node in hash table */ | ||||||
|  | --- a/drivers/net/ethernet/qualcomm/essedma/edma_ethtool.c | ||||||
|  | +++ b/drivers/net/ethernet/qualcomm/essedma/edma_ethtool.c | ||||||
|  | @@ -78,6 +78,7 @@ static const struct edma_ethtool_stats e | ||||||
|  |  	{"rx_q6_byte", EDMA_STAT(rx_q6_byte)}, | ||||||
|  |  	{"rx_q7_byte", EDMA_STAT(rx_q7_byte)}, | ||||||
|  |  	{"tx_desc_error", EDMA_STAT(tx_desc_error)}, | ||||||
|  | +	{"rx_alloc_fail_ctr", EDMA_STAT(rx_alloc_fail_ctr)}, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  #define EDMA_STATS_LEN ARRAY_SIZE(edma_gstrings_stats) | ||||||
		Reference in New Issue
	
	Block a user
	 Christian Lamparter
					Christian Lamparter