[bug report] wifi: ath12k: resource leak in ath12k_dp_srng_setup()

Dan Carpenter
2023-02-16T13:59:30Z

Hello Kalle Valo,

The patch d889913205cf: "wifi: ath12k: driver for Qualcomm Wi-Fi 7
devices" from Nov 28, 2022, leads to the following Smatch static
checker warning:

drivers/net/wireless/ath/ath12k/dp.c:310 ath12k_dp_srng_setup() warn: 'ring->vaddr_unaligned' from dma_alloc_coherent() not released on lines: 298,305.

drivers/net/wireless/ath/ath12k/dp.c
217 int ath12k_dp_srng_setup(struct ath12k_base *ab, struct dp_srng *ring,
218 enum hal_ring_type type, int ring_num,
219 int mac_id, int num_entries)
220 {
221 struct hal_srng_params params = { 0 };
222 int entry_sz = ath12k_hal_srng_get_entrysize(ab, type);
223 int max_entries = ath12k_hal_srng_get_max_entries(ab, type);
224 int ret;
225
226 if (max_entries < 0 || entry_sz < 0)
227 return -EINVAL;
228
229 if (num_entries > max_entries)
230 num_entries = max_entries;
231
232 ring->size = (num_entries * entry_sz) + HAL_RING_BASE_ALIGN - 1;
233 ring->vaddr_unaligned = dma_alloc_coherent(ab->dev, ring->size,
234 &ring->paddr_unaligned,
235 GFP_KERNEL);
236 if (!ring->vaddr_unaligned)
237 return -ENOMEM;
238
239 ring->vaddr = PTR_ALIGN(ring->vaddr_unaligned, HAL_RING_BASE_ALIGN);
240 ring->paddr = ring->paddr_unaligned + ((unsigned long)ring->vaddr -
241 (unsigned long)ring->vaddr_unaligned);
242
243 params.ring_base_vaddr = ring->vaddr;
244 params.ring_base_paddr = ring->paddr;
245 params.num_entries = num_entries;
246 ath12k_dp_srng_msi_setup(ab, &params, type, ring_num + mac_id);
247
248 switch (type) {
249 case HAL_REO_DST:
250 params.intr_batch_cntr_thres_entries =
251 HAL_SRNG_INT_BATCH_THRESHOLD_RX;
252 params.intr_timer_thres_us = HAL_SRNG_INT_TIMER_THRESHOLD_RX;
253 break;
254 case HAL_RXDMA_BUF:
255 case HAL_RXDMA_MONITOR_BUF:
256 case HAL_RXDMA_MONITOR_STATUS:
257 params.low_threshold = num_entries >> 3;
258 params.flags |= HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN;
259 params.intr_batch_cntr_thres_entries = 0;
260 params.intr_timer_thres_us = HAL_SRNG_INT_TIMER_THRESHOLD_RX;
261 break;
262 case HAL_TX_MONITOR_DST:
263 params.low_threshold = DP_TX_MONITOR_BUF_SIZE_MAX >> 3;
264 params.flags |= HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN;
265 params.intr_batch_cntr_thres_entries = 0;
266 params.intr_timer_thres_us = HAL_SRNG_INT_TIMER_THRESHOLD_RX;
267 break;
268 case HAL_WBM2SW_RELEASE:
269 if (ab->hw_params->hw_ops->dp_srng_is_tx_comp_ring(ring_num)) {
270 params.intr_batch_cntr_thres_entries =
271 HAL_SRNG_INT_BATCH_THRESHOLD_TX;
272 params.intr_timer_thres_us =
273 HAL_SRNG_INT_TIMER_THRESHOLD_TX;
274 break;
275 }
276 /* follow through when ring_num != HAL_WBM2SW_REL_ERR_RING_NUM */
277 fallthrough;
278 case HAL_REO_EXCEPTION:
279 case HAL_REO_REINJECT:
280 case HAL_REO_CMD:
281 case HAL_REO_STATUS:
282 case HAL_TCL_DATA:
283 case HAL_TCL_CMD:
284 case HAL_TCL_STATUS:
285 case HAL_WBM_IDLE_LINK:
286 case HAL_SW2WBM_RELEASE:
287 case HAL_RXDMA_DST:
288 case HAL_RXDMA_MONITOR_DST:
289 case HAL_RXDMA_MONITOR_DESC:
290 params.intr_batch_cntr_thres_entries =
291 HAL_SRNG_INT_BATCH_THRESHOLD_OTHER;
292 params.intr_timer_thres_us = HAL_SRNG_INT_TIMER_THRESHOLD_OTHER;
293 break;
294 case HAL_RXDMA_DIR_BUF:
295 break;
296 default:
297 ath12k_warn(ab, "Not a valid ring type in dp :%d\n", type);
298 return -EINVAL;

ring->vaddr_unaligned not released on error path.

299 }
300
301 ret = ath12k_hal_srng_setup(ab, type, ring_num, mac_id, &params);
302 if (ret < 0) {
303 ath12k_warn(ab, "failed to setup srng: %d ring_id %d\n",
304 ret, ring_num);
305 return ret;
306 }
307
308 ring->ring_id = ret;
309
--> 310 return 0;
311 }

regards,
dan carpenter

--
ath12k mailing list
ath12k@lists.infradead.org