Thread (18 messages) 18 messages, 5 authors, 2016-01-29

[PATCH net-next 03/10] net: mvneta: bm: add support for hardware buffer management

From: Marcin Wojtas <hidden>
Date: 2016-01-12 20:12:29
Also in: lkml, netdev

Hi Gregory,

I have two remarks to my own code. Please let me know before patch v2,
I will provide you with corrected version (I already did it locally).
quoted hunk ↗ jump to hunk
@@ -1556,17 +1777,20 @@ static void mvneta_rxq_drop_pkts(struct mvneta_port *pp,
        int rx_done, i;

        rx_done = mvneta_rxq_busy_desc_num_get(pp, rxq);
+       if (rx_done)
+               mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_done);
+
+       if (pp->bm_priv)
+               return;
+
This is wrong - buffers that are supposed to be dropped should return
to bm_pool.
quoted hunk ↗ jump to hunk
@@ -1587,23 +1812,35 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo,

        rx_done = 0;

+       bm_in_use = pp->bm_priv ? true : false;
+
        /* Fairness NAPI loop */
        while (rx_done < rx_todo) {
                struct mvneta_rx_desc *rx_desc = mvneta_rxq_next_desc_get(rxq);
+               struct mvneta_bm_pool *bm_pool = NULL;
                struct sk_buff *skb;
                unsigned char *data;
                dma_addr_t phys_addr;
-               u32 rx_status;
+               u32 rx_status, frag_size;
                int rx_bytes, err;
+               u8 pool_id;

                rx_done++;
                rx_status = rx_desc->status;
                rx_bytes = rx_desc->data_size - (ETH_FCS_LEN + MVNETA_MH_SIZE);
                data = (unsigned char *)rx_desc->buf_cookie;
                phys_addr = rx_desc->buf_phys_addr;
+               if (bm_in_use) {
+                       pool_id = MVNETA_RX_GET_BM_POOL_ID(rx_desc);
+                       bm_pool = &pp->bm_priv->bm_pools[pool_id];
+               }

                if (!mvneta_rxq_desc_is_first_last(rx_status) ||
                    (rx_status & MVNETA_RXD_ERR_SUMMARY)) {
+                       /* Return the buffer to the pool */
+                       if (bm_in_use)
+                               mvneta_bm_pool_put_bp(pp->bm_priv, bm_pool,
+                                                     rx_desc->buf_phys_addr);
                err_drop_frame:
                        dev->stats.rx_errors++;
                        mvneta_rx_error(pp, rx_desc);
@@ -1633,25 +1870,38 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo,
                        rcvd_pkts++;
                        rcvd_bytes += rx_bytes;

+                       /* Return the buffer to the pool */
+                       if (bm_in_use)
+                               mvneta_bm_pool_put_bp(pp->bm_priv, bm_pool,
+                                                     rx_desc->buf_phys_addr);
+
                        /* leave the descriptor and buffer untouched */
                        continue;
                }

                /* Refill processing */
-               err = mvneta_rx_refill(pp, rx_desc);
+               err = bm_in_use ? mvneta_bm_pool_refill(pp->bm_priv, bm_pool) :
+                                 mvneta_rx_refill(pp, rx_desc);
                if (err) {
                        netdev_err(dev, "Linux processing - Can't refill\n");
                        rxq->missed++;
                        goto err_drop_frame;
Wrong - on refill fail, original buffer should be returned to bm_pool.
Same case is, when netdev_alloc_skb_ip_align fail inside copybreak
(this should also be fixed).

Best regards,
Marcin
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help