Skip to content

Commit

Permalink
ath11k: use cache line aligned buffers for dbring
Browse files Browse the repository at this point in the history
The DMA buffers of dbring which is used for spectral/cfr
starts at certain offset from original kmalloc() returned buffer.
This is not cache line aligned.
And also driver tries to access the data that is immediately before
this offset address (i.e. buff->paddr) after doing dma map.
This will cause cache line sharing issues and data corruption,
if CPU happen to write back cache after HW has dma'ed the data.

Fix this by mapping a cache line aligned buffer to dma.

Tested on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1

Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/1635831693-15962-1-git-send-email-quic_ramess@quicinc.com
  • Loading branch information
Rameshkumar Sundaram authored and Kalle Valo committed Nov 17, 2021
1 parent f951380 commit bd77f6b
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 5 deletions.
16 changes: 12 additions & 4 deletions drivers/net/wireless/ath/ath11k/dbring.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,23 @@ static int ath11k_dbring_fill_bufs(struct ath11k *ar,
req_entries = min(num_free, ring->bufs_max);
num_remain = req_entries;
align = ring->buf_align;
size = sizeof(*buff) + ring->buf_sz + align - 1;
size = ring->buf_sz + align - 1;

while (num_remain > 0) {
buff = kzalloc(size, GFP_ATOMIC);
buff = kzalloc(sizeof(*buff), GFP_ATOMIC);
if (!buff)
break;

buff->payload = kzalloc(size, GFP_ATOMIC);
if (!buff->payload) {
kfree(buff);
break;
}
ret = ath11k_dbring_bufs_replenish(ar, ring, buff);
if (ret) {
ath11k_warn(ar->ab, "failed to replenish db ring num_remain %d req_ent %d\n",
num_remain, req_entries);
kfree(buff->payload);
kfree(buff);
break;
}
Expand Down Expand Up @@ -282,7 +288,7 @@ int ath11k_dbring_buffer_release_event(struct ath11k_base *ab,

srng = &ab->hal.srng_list[ring->refill_srng.ring_id];
num_entry = ev->fixed.num_buf_release_entry;
size = sizeof(*buff) + ring->buf_sz + ring->buf_align - 1;
size = ring->buf_sz + ring->buf_align - 1;
num_buff_reaped = 0;

spin_lock_bh(&srng->lock);
Expand Down Expand Up @@ -319,7 +325,8 @@ int ath11k_dbring_buffer_release_event(struct ath11k_base *ab,
ring->handler(ar, &handler_data);
}

memset(buff, 0, size);
buff->paddr = 0;
memset(buff->payload, 0, size);
ath11k_dbring_bufs_replenish(ar, ring, buff);
}

Expand All @@ -346,6 +353,7 @@ void ath11k_dbring_buf_cleanup(struct ath11k *ar, struct ath11k_dbring *ring)
idr_remove(&ring->bufs_idr, buf_id);
dma_unmap_single(ar->ab->dev, buff->paddr,
ring->buf_sz, DMA_FROM_DEVICE);
kfree(buff->payload);
kfree(buff);
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/ath/ath11k/dbring.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

struct ath11k_dbring_element {
dma_addr_t paddr;
u8 payload[0];
u8 *payload;
};

struct ath11k_dbring_data {
Expand Down

0 comments on commit bd77f6b

Please sign in to comment.