ソースを参照

qcacld-3.0: fix API mismatch for vendor command processing

Some skb for vendor command reply is allocated with internal
API but reply/free is done with kernel APIs, which will break
the buffer tracking once NBUF_MEMORY_DEBUG and NETLINK_BUF_TRACK
are enabled.

To fix it, replace kernel APIs with internal APIs accordingly:
Replace cfg80211_vendor_cmd_reply() with
wlan_cfg80211_vendor_cmd_reply().
Replace kfree_skb() with wlan_cfg80211_vendor_free_skb().

Change-Id: If4f37b5dca5483a9b64c726d37d3959d3ecd699e
CRs-Fixed: 3350756
Yu Wang 2 年 前
コミット
2294db2698

+ 3 - 5
core/hdd/src/wlan_hdd_cfg80211.c

@@ -7397,12 +7397,12 @@ __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
 	}
 
 	qdf_mem_free(firmware_version);
-	return cfg80211_vendor_cmd_reply(reply_skb);
+	return wlan_cfg80211_vendor_cmd_reply(reply_skb);
 
 error_nla_fail:
 	hdd_err("nla put fail");
 	qdf_mem_free(firmware_version);
-	kfree_skb(reply_skb);
+	wlan_cfg80211_vendor_free_skb(reply_skb);
 	return -EINVAL;
 }
 
@@ -14990,12 +14990,10 @@ __wlan_hdd_cfg80211_get_radio_combination_matrix(struct wiphy *wiphy,
 		nla_nest_end(reply_skb, combination);
 	}
 	nla_nest_end(reply_skb, combination_cfg);
-	ret = wlan_cfg80211_vendor_cmd_reply(reply_skb);
+	return wlan_cfg80211_vendor_cmd_reply(reply_skb);
 
-	return ret;
 err:
 	wlan_cfg80211_vendor_free_skb(reply_skb);
-
 	return ret;
 }
 

+ 1 - 1
core/hdd/src/wlan_hdd_oemdata.c

@@ -1448,7 +1448,7 @@ __wlan_hdd_cfg80211_oem_data_handler(struct wiphy *wiphy,
 		if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_OEM_DATA_CMD_DATA,
 			    get_oem_data->data_len, get_oem_data->data)) {
 			hdd_err("nla put failure");
-			kfree_skb(skb);
+			wlan_cfg80211_vendor_free_skb(skb);
 			ret =  -EINVAL;
 			goto err;
 		}

+ 2 - 4
core/hdd/src/wlan_hdd_thermal.c

@@ -427,10 +427,8 @@ hdd_get_curr_thermal_stats_val(struct wiphy *wiphy,
 		    nla_put_u32(skb, THERMAL_LVL_COUNT,
 				get_tt_stats->level_info[i].num_entry)) {
 			hdd_err("nla put failure");
-			kfree_skb(skb);
 			ret =  -EINVAL;
-			hdd_ctx->is_therm_stats_in_progress = false;
-			break;
+			goto nla_failed;
 		}
 		nla_nest_end(skb, tt_levels);
 	}
@@ -439,7 +437,7 @@ hdd_get_curr_thermal_stats_val(struct wiphy *wiphy,
 	goto completed;
 
 nla_failed:
-	kfree_skb(skb);
+	wlan_cfg80211_vendor_free_skb(skb);
 completed:
 	hdd_ctx->is_therm_stats_in_progress = false;
 	osif_request_put(request);

+ 13 - 14
core/hdd/src/wlan_hdd_twt.c

@@ -1000,12 +1000,12 @@ hdd_twt_pack_get_params_resp(struct hdd_context *hdd_ctx,
 	if (QDF_IS_STATUS_ERROR(qdf_status))
 		goto fail;
 
-	if (cfg80211_vendor_cmd_reply(reply_skb))
+	if (wlan_cfg80211_vendor_cmd_reply(reply_skb))
 		qdf_status = QDF_STATUS_E_INVAL;
-fail:
-	if (QDF_IS_STATUS_ERROR(qdf_status) && reply_skb)
-		kfree_skb(reply_skb);
+	return qdf_status;
 
+fail:
+	wlan_cfg80211_vendor_free_skb(reply_skb);
 	return qdf_status;
 }
 
@@ -3528,6 +3528,7 @@ hdd_twt_pack_get_capabilities_resp(struct hdd_adapter *adapter)
 	uint8_t peer_cap = 0, self_cap = 0;
 	bool twt_req = false, twt_bcast_req = false;
 	bool is_twt_24ghz_allowed = true;
+	int ret;
 
 	/*
 	 * Length of attribute QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF &
@@ -3594,13 +3595,11 @@ hdd_twt_pack_get_capabilities_resp(struct hdd_adapter *adapter)
 
 	nla_nest_end(reply_skb, config_attr);
 
-	if (cfg80211_vendor_cmd_reply(reply_skb))
-		qdf_status = QDF_STATUS_E_INVAL;
+	ret = wlan_cfg80211_vendor_cmd_reply(reply_skb);
+	return qdf_status_from_os_return(ret);
 
 free_skb:
-	if (QDF_IS_STATUS_ERROR(qdf_status) && reply_skb)
-		kfree_skb(reply_skb);
-
+	wlan_cfg80211_vendor_free_skb(reply_skb);
 	return qdf_status;
 }
 
@@ -4003,7 +4002,7 @@ hdd_twt_request_session_traffic_stats(struct hdd_adapter *adapter,
 							peer_mac,
 							&errno);
 	if (!event)
-		return errno;
+		return qdf_status_from_os_return(errno);
 
 	skb_len = hdd_get_twt_get_stats_event_len();
 	reply_skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(
@@ -4011,7 +4010,7 @@ hdd_twt_request_session_traffic_stats(struct hdd_adapter *adapter,
 						skb_len);
 	if (!reply_skb) {
 		hdd_err("Get stats - alloc reply_skb failed");
-		errno = -ENOMEM;
+		status = QDF_STATUS_E_NOMEM;
 		goto free_event;
 	}
 
@@ -4022,14 +4021,14 @@ hdd_twt_request_session_traffic_stats(struct hdd_adapter *adapter,
 						event->num_twt_infra_cp_stats);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		hdd_err("Get stats - Failed to pack nl response");
-		errno = qdf_status_to_os_return(status);
 		goto free_skb;
 	}
 
 	qdf_mem_free(event->twt_infra_cp_stats);
 	qdf_mem_free(event);
 
-	return wlan_cfg80211_vendor_cmd_reply(reply_skb);
+	errno = wlan_cfg80211_vendor_cmd_reply(reply_skb);
+	return qdf_status_from_os_return(errno);
 
 free_skb:
 	wlan_cfg80211_vendor_free_skb(reply_skb);
@@ -4038,7 +4037,7 @@ free_event:
 	qdf_mem_free(event->twt_infra_cp_stats);
 	qdf_mem_free(event);
 
-	return errno;
+	return status;
 }
 
 /**

+ 2 - 2
os_if/twt/src/osif_twt_ext_req.c

@@ -1921,12 +1921,12 @@ osif_twt_send_get_params_resp(struct wlan_objmgr_vdev *vdev,
 	if (QDF_IS_STATUS_ERROR(qdf_status))
 		goto fail;
 
-	if (cfg80211_vendor_cmd_reply(reply_skb))
+	if (wlan_cfg80211_vendor_cmd_reply(reply_skb))
 		qdf_status = QDF_STATUS_E_INVAL;
 
 	return qdf_status;
 fail:
-	kfree_skb(reply_skb);
+	wlan_cfg80211_vendor_free_skb(reply_skb);
 	return qdf_status;
 }
 

+ 6 - 5
os_if/twt/src/osif_twt_ext_rsp.c

@@ -802,13 +802,12 @@ osif_twt_send_get_capabilities_response(struct wlan_objmgr_psoc *psoc,
 
 	nla_nest_end(reply_skb, config_attr);
 
-	if (cfg80211_vendor_cmd_reply(reply_skb))
+	if (wlan_cfg80211_vendor_cmd_reply(reply_skb))
 		qdf_status = QDF_STATUS_E_INVAL;
+	return qdf_status;
 
 free_skb:
-	if (QDF_IS_STATUS_ERROR(qdf_status) && reply_skb)
-		kfree_skb(reply_skb);
-
+	wlan_cfg80211_vendor_free_skb(reply_skb);
 	return qdf_status;
 }
 
@@ -1555,6 +1554,7 @@ QDF_STATUS osif_twt_get_stats_response(struct wlan_objmgr_vdev *vdev,
 	struct wireless_dev *wdev;
 	QDF_STATUS status = QDF_STATUS_E_INVAL;
 	struct sk_buff *reply_skb;
+	int ret;
 
 	osif_priv = wlan_vdev_get_ospriv(vdev);
 	if (!osif_priv) {
@@ -1584,6 +1584,7 @@ QDF_STATUS osif_twt_get_stats_response(struct wlan_objmgr_vdev *vdev,
 		return qdf_status_to_os_return(status);
 	}
 
-	return wlan_cfg80211_vendor_cmd_reply(reply_skb);
+	ret = wlan_cfg80211_vendor_cmd_reply(reply_skb);
+	return qdf_status_from_os_return(ret);
 }