12e5d15795de5ebaa8b21e91da8931e6477311ec
[openwrt/staging/ynezz.git] /
1 From 1f00fa355829b510beb900ce1136f40802e6076e Mon Sep 17 00:00:00 2001
2 From: Camelia Groza <camelia.groza@nxp.com>
3 Date: Mon, 10 Sep 2018 14:31:05 +0300
4 Subject: [PATCH] sdk_dpaa: store the skb backpointer in the skb headroom
5
6 The skb backpointer is stored right before the FMan buffer, in order to
7 avoid overwriting. The memory area storing the backpointer was outside of
8 the skb. This made it hard to guarantee its size.
9
10 This patch changes the layout of the skb at buffer seed time: the area
11 reserved for storing the skb backpointer is part of the skb's headroom.
12 This makes it easier to track if the backpointer can be safely stored
13 when recycling the buffer.
14
15 Signed-off-by: Camelia Groza <camelia.groza@nxp.com>
16 ---
17 .../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 33 ++++++++++++++++------
18 1 file changed, 24 insertions(+), 9 deletions(-)
19
20 --- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
21 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
22 @@ -82,8 +82,8 @@ static void dpa_bp_recycle_frag(struct d
23
24 static int _dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp)
25 {
26 + void *new_buf, *fman_buf;
27 struct bm_buffer bmb[8];
28 - void *new_buf;
29 dma_addr_t addr;
30 uint8_t i;
31 struct device *dev = dpa_bp->dev;
32 @@ -113,21 +113,37 @@ static int _dpa_bp_add_8_bufs(const stru
33
34 if (unlikely(!new_buf))
35 goto netdev_alloc_failed;
36 - new_buf = PTR_ALIGN(new_buf + SMP_CACHE_BYTES, SMP_CACHE_BYTES);
37 + new_buf = PTR_ALIGN(new_buf, SMP_CACHE_BYTES);
38
39 - skb = build_skb(new_buf, DPA_SKB_SIZE(dpa_bp->size) +
40 - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
41 + /* Apart from the buffer that will be used by the FMan, the
42 + * skb also guarantees enough space to hold the backpointer
43 + * in the headroom and the shared info at the end.
44 + */
45 + skb = build_skb(new_buf,
46 + SMP_CACHE_BYTES + DPA_SKB_SIZE(dpa_bp->size) +
47 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
48 if (unlikely(!skb)) {
49 put_page(virt_to_head_page(new_buf));
50 goto build_skb_failed;
51 }
52
53 - /* Store the skb back-pointer before the start of the buffer.
54 - * Otherwise it will be overwritten by the FMan.
55 + /* Reserve SMP_CACHE_BYTES in the skb's headroom to store the
56 + * backpointer. This area will not be synced to, or
57 + * overwritten by, the FMan.
58 + */
59 + skb_reserve(skb, SMP_CACHE_BYTES);
60 +
61 + /* We don't sync the first SMP_CACHE_BYTES of the buffer to
62 + * the FMan. The skb backpointer is stored at the end of the
63 + * reserved headroom. Otherwise it will be overwritten by the
64 + * FMan.
65 + * The buffer synced with the FMan starts right after the
66 + * reserved headroom.
67 */
68 - DPA_WRITE_SKB_PTR(skb, skbh, new_buf, -1);
69 + fman_buf = new_buf + SMP_CACHE_BYTES;
70 + DPA_WRITE_SKB_PTR(skb, skbh, fman_buf, -1);
71
72 - addr = dma_map_single(dev, new_buf,
73 + addr = dma_map_single(dev, fman_buf,
74 dpa_bp->size, DMA_BIDIRECTIONAL);
75 if (unlikely(dma_mapping_error(dev, addr)))
76 goto dma_map_failed;
77 @@ -477,7 +493,6 @@ static struct sk_buff *__hot sg_fd_to_sk
78 DMA_BIDIRECTIONAL);
79 if (i == 0) {
80 DPA_READ_SKB_PTR(skb, skbh, sg_vaddr, -1);
81 - DPA_BUG_ON(skb->head != sg_vaddr);
82 #ifdef CONFIG_FSL_DPAA_1588
83 if (priv->tsu && priv->tsu->valid &&
84 priv->tsu->hwts_rx_en_ioctl)