[bug report] net: mvneta: add frags support to XDP_TX

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Lorenzo Bianconi,

This is a semi-automatic email about new static checker warnings.

The patch c41ced023a98: "net: mvneta: add frags support to XDP_TX"
from Jan 21, 2022, leads to the following Smatch complaint:

    drivers/net/ethernet/marvell/mvneta.c:2145 mvneta_xdp_submit_frame()
    warn: variable dereferenced before check 'tx_desc' (see line 2136)

drivers/net/ethernet/marvell/mvneta.c
  2080        static int
  2081        mvneta_xdp_submit_frame(struct mvneta_port *pp, struct mvneta_tx_queue *txq,
  2082                                struct xdp_frame *xdpf, int *nxmit_byte, bool dma_map)
  2083        {
  2084                struct skb_shared_info *sinfo = xdp_get_shared_info_from_frame(xdpf);
  2085                struct device *dev = pp->dev->dev.parent;
  2086                struct mvneta_tx_desc *tx_desc = NULL;
  2087                int i, num_frames = 1;
  2088                struct page *page;
  2089
  2090                if (unlikely(xdp_frame_has_frags(xdpf)))
  2091                        num_frames += sinfo->nr_frags;
  2092
  2093                if (txq->count + num_frames >= txq->size)
  2094                        return MVNETA_XDP_DROPPED;
  2095
  2096                for (i = 0; i < num_frames; i++) {

We know num_frames is non-zero

  2097                        struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index];
  2098                        skb_frag_t *frag = NULL;
  2099                        int len = xdpf->len;
  2100                        dma_addr_t dma_addr;
  2101
  2102                        if (unlikely(i)) { /* paged area */
  2103                                frag = &sinfo->frags[i - 1];
  2104                                len = skb_frag_size(frag);
  2105                        }
  2106
  2107                        tx_desc = mvneta_txq_next_desc_get(txq);
  2108                        if (dma_map) {
  2109                                /* ndo_xdp_xmit */
  2110                                void *data;
  2111
  2112                                data = unlikely(frag) ? skb_frag_address(frag)
  2113                                                      : xdpf->data;
  2114                                dma_addr = dma_map_single(dev, data, len,
  2115                                                          DMA_TO_DEVICE);
  2116                                if (dma_mapping_error(dev, dma_addr)) {
  2117                                        mvneta_txq_desc_put(txq);
  2118                                        goto unmap;
  2119                                }
  2120
  2121                                buf->type = MVNETA_TYPE_XDP_NDO;
  2122                        } else {
  2123                                page = unlikely(frag) ? skb_frag_page(frag)
  2124                                                      : virt_to_page(xdpf->data);
  2125                                dma_addr = page_pool_get_dma_addr(page);
  2126                                if (unlikely(frag))
  2127                                        dma_addr += skb_frag_off(frag);
  2128                                else
  2129                                        dma_addr += sizeof(*xdpf) + xdpf->headroom;
  2130                                dma_sync_single_for_device(dev, dma_addr, len,
  2131                                                           DMA_BIDIRECTIONAL);
  2132                                buf->type = MVNETA_TYPE_XDP_TX;
  2133                        }
  2134                        buf->xdpf = unlikely(i) ? NULL : xdpf;
  2135
  2136                        tx_desc->command = unlikely(i) ? 0 : MVNETA_TXD_F_DESC;
                              ^^^^^^^^^^^^^^^^
Dereferenced

  2137                        tx_desc->buf_phys_addr = dma_addr;
  2138                        tx_desc->data_size = len;
  2139                        *nxmit_byte += len;
  2140
  2141                        mvneta_txq_inc_put(txq);
  2142                }
  2143
  2144                /*last descriptor */
  2145                if (likely(tx_desc))
                                 ^^^^^^^
Checked after dereference.

  2146                        tx_desc->command |= MVNETA_TXD_L_DESC | MVNETA_TXD_Z_PAD;
  2147
  2148                txq->pending += num_frames;
  2149                txq->count += num_frames;
  2150
  2151                return MVNETA_XDP_TX;
  2152
  2153        unmap:
  2154                for (i--; i >= 0; i--) {
  2155                        mvneta_txq_desc_put(txq);
  2156                        tx_desc = txq->descs + txq->next_desc_to_proc;
  2157                        dma_unmap_single(dev, tx_desc->buf_phys_addr,
  2158                                         tx_desc->data_size,

regards,
dan carpenter



[Index of Archives]     [Kernel Development]     [Kernel Announce]     [Kernel Newbies]     [Linux Networking Development]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Device Mapper]

  Powered by Linux