Просмотр исходного кода

qcacld-3.0: Do not requeue back GRO_DROPed skb

napi_gro_receive packet frees skb on success or drop(GRO_DROP).
Current code is trying to handle failure case by delivering skb
via non napi_gro_receive API. In case the packet is dropped by GRO,
this leads to access of freed skb.
Donot requeue GRO dropped skb to network stack.

Change-Id: Ibfbb8d4ac7f77cf3547da8c2ebc4f3fea8d226d0
CRs-Fixed: 2409252
Manjunathappa Prakash 6 лет назад
Родитель
Сommit
78b6a88213
3 измененных файлов с 17 добавлено и 10 удалено
  1. 1 0
      core/hdd/inc/wlan_hdd_main.h
  2. 3 3
      core/hdd/src/wlan_hdd_stats.c
  3. 13 7
      core/hdd/src/wlan_hdd_tx_rx.c

+ 1 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -440,6 +440,7 @@ struct hdd_tx_rx_stats {
 	qdf_atomic_t rx_usolict_arp_n_mcast_drp;
 	/* rx gro */
 	__u32 rx_aggregated;
+	__u32 rx_gro_dropped;
 	__u32 rx_non_aggregated;
 	__u32 rx_gro_flushes;
 	/* Dynamic GRO disable/enable, flush may be required for UDP GRO */

+ 3 - 3
core/hdd/src/wlan_hdd_stats.c

@@ -6229,13 +6229,13 @@ void wlan_hdd_display_txrx_stats(struct hdd_context *ctx)
 				  i, stats->rx_packets[i], stats->rx_dropped[i],
 				  stats->rx_delivered[i], stats->rx_refused[i]);
 		}
-		hdd_debug("RX - packets %u, dropped %u, unsolict_arp_n_mcast_drp %u, delivered %u, refused %u GRO - agg %u non-agg %u flushes(%u %u) disabled(conc %u low-tput %u)",
+		hdd_debug("RX - packets %u, dropped %u, unsolict_arp_n_mcast_drp %u, delivered %u, refused %u GRO - agg %u drop %u non-agg %u flushes(%u %u) disabled(conc %u low-tput %u)",
 			  total_rx_pkt, total_rx_dropped,
 			  qdf_atomic_read(&stats->rx_usolict_arp_n_mcast_drp),
 			  total_rx_delv,
 			  total_rx_refused, stats->rx_aggregated,
-			  stats->rx_non_aggregated, stats->rx_gro_flushes,
-			  stats->rx_gro_force_flushes,
+			  stats->rx_gro_dropped, stats->rx_non_aggregated,
+			  stats->rx_gro_flushes, stats->rx_gro_force_flushes,
 			  qdf_atomic_read(&ctx->disable_rx_ol_in_concurrency),
 			  qdf_atomic_read(&ctx->disable_rx_ol_in_low_tput));
 	}

+ 13 - 7
core/hdd/src/wlan_hdd_tx_rx.c

@@ -1569,7 +1569,7 @@ static QDF_STATUS hdd_gro_rx_bh_disable(struct hdd_adapter *adapter,
 					struct napi_struct *napi_to_use,
 					struct sk_buff *skb)
 {
-	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	gro_result_t gro_res;
 	bool flush_ind = QDF_NBUF_CB_RX_FLUSH_IND(skb);
 
@@ -1581,8 +1581,8 @@ static QDF_STATUS hdd_gro_rx_bh_disable(struct hdd_adapter *adapter,
 		napi_gro_flush(napi_to_use, false);
 	local_bh_enable();
 
-	if (gro_res != GRO_DROP)
-		status = QDF_STATUS_SUCCESS;
+	if (gro_res == GRO_DROP)
+		status = QDF_STATUS_E_GRO_DROP;
 
 	if (flush_ind)
 		adapter->hdd_stats.tx_rx_stats.rx_gro_flushes++;
@@ -1936,12 +1936,18 @@ QDF_STATUS hdd_rx_deliver_to_stack(struct hdd_adapter *adapter,
 	    !QDF_NBUF_CB_RX_PEER_CACHED_FRM(skb))
 		skb_receive_offload_ok = true;
 
-	if (skb_receive_offload_ok && hdd_ctx->receive_offload_cb)
+	if (skb_receive_offload_ok && hdd_ctx->receive_offload_cb) {
 		status = hdd_ctx->receive_offload_cb(adapter, skb);
 
-	if (QDF_IS_STATUS_SUCCESS(status)) {
-		adapter->hdd_stats.tx_rx_stats.rx_aggregated++;
-		return status;
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			adapter->hdd_stats.tx_rx_stats.rx_aggregated++;
+			return status;
+		}
+
+		if (status == QDF_STATUS_E_GRO_DROP) {
+			adapter->hdd_stats.tx_rx_stats.rx_gro_dropped++;
+			return status;
+		}
 	}
 
 	adapter->hdd_stats.tx_rx_stats.rx_non_aggregated++;