net: introduce page_frag_cache_drain()
authorYunsheng Lin <linyunsheng@huawei.com>
Wed, 28 Feb 2024 09:30:10 +0000 (17:30 +0800)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 5 Mar 2024 10:38:14 +0000 (11:38 +0100)
When draining a page_frag_cache, most user are doing
the similar steps, so introduce an API to avoid code
duplication.

Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ethernet/google/gve/gve_main.c
drivers/net/ethernet/mediatek/mtk_wed_wo.c
drivers/nvme/host/tcp.c
drivers/nvme/target/tcp.c
include/linux/gfp.h
mm/page_alloc.c

index 7b89b66adb5325e1bbc76a52c2d72258f990625e..166bd827a6d7131414425e14255812f246af15e9 100644 (file)
@@ -1276,17 +1276,10 @@ static void gve_unreg_xdp_info(struct gve_priv *priv)
 
 static void gve_drain_page_cache(struct gve_priv *priv)
 {
-       struct page_frag_cache *nc;
        int i;
 
-       for (i = 0; i < priv->rx_cfg.num_queues; i++) {
-               nc = &priv->rx[i].page_cache;
-               if (nc->va) {
-                       __page_frag_cache_drain(virt_to_page(nc->va),
-                                               nc->pagecnt_bias);
-                       nc->va = NULL;
-               }
-       }
+       for (i = 0; i < priv->rx_cfg.num_queues; i++)
+               page_frag_cache_drain(&priv->rx[i].page_cache);
 }
 
 static void gve_qpls_get_curr_alloc_cfg(struct gve_priv *priv,
index d58b07e7e123994d5c82ef5fb08e2744eb531ab3..7063c78bd35fd30d98c4720ca3f3a542398ce2c6 100644 (file)
@@ -286,7 +286,6 @@ mtk_wed_wo_queue_free(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q)
 static void
 mtk_wed_wo_queue_tx_clean(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q)
 {
-       struct page *page;
        int i;
 
        for (i = 0; i < q->n_desc; i++) {
@@ -301,19 +300,12 @@ mtk_wed_wo_queue_tx_clean(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q)
                entry->buf = NULL;
        }
 
-       if (!q->cache.va)
-               return;
-
-       page = virt_to_page(q->cache.va);
-       __page_frag_cache_drain(page, q->cache.pagecnt_bias);
-       memset(&q->cache, 0, sizeof(q->cache));
+       page_frag_cache_drain(&q->cache);
 }
 
 static void
 mtk_wed_wo_queue_rx_clean(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q)
 {
-       struct page *page;
-
        for (;;) {
                void *buf = mtk_wed_wo_dequeue(wo, q, NULL, true);
 
@@ -323,12 +315,7 @@ mtk_wed_wo_queue_rx_clean(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q)
                skb_free_frag(buf);
        }
 
-       if (!q->cache.va)
-               return;
-
-       page = virt_to_page(q->cache.va);
-       __page_frag_cache_drain(page, q->cache.pagecnt_bias);
-       memset(&q->cache, 0, sizeof(q->cache));
+       page_frag_cache_drain(&q->cache);
 }
 
 static void
index a6d596e05602117ff9c38fbcb86645bda4016c59..3692b56cb58dbacf53eba56aef841dc50063557a 100644 (file)
@@ -1344,7 +1344,6 @@ static int nvme_tcp_alloc_async_req(struct nvme_tcp_ctrl *ctrl)
 
 static void nvme_tcp_free_queue(struct nvme_ctrl *nctrl, int qid)
 {
-       struct page *page;
        struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl);
        struct nvme_tcp_queue *queue = &ctrl->queues[qid];
        unsigned int noreclaim_flag;
@@ -1355,11 +1354,7 @@ static void nvme_tcp_free_queue(struct nvme_ctrl *nctrl, int qid)
        if (queue->hdr_digest || queue->data_digest)
                nvme_tcp_free_crypto(queue);
 
-       if (queue->pf_cache.va) {
-               page = virt_to_head_page(queue->pf_cache.va);
-               __page_frag_cache_drain(page, queue->pf_cache.pagecnt_bias);
-               queue->pf_cache.va = NULL;
-       }
+       page_frag_cache_drain(&queue->pf_cache);
 
        noreclaim_flag = memalloc_noreclaim_save();
        /* ->sock will be released by fput() */
index c8655fc5aa5b8aac838cb4c2e4c0a76c8ebbc174..2aa5762e9f50d0d3ae3c6cfceb9cd03ce1ad8df4 100644 (file)
@@ -1591,7 +1591,6 @@ static void nvmet_tcp_free_cmd_data_in_buffers(struct nvmet_tcp_queue *queue)
 
 static void nvmet_tcp_release_queue_work(struct work_struct *w)
 {
-       struct page *page;
        struct nvmet_tcp_queue *queue =
                container_of(w, struct nvmet_tcp_queue, release_work);
 
@@ -1615,8 +1614,7 @@ static void nvmet_tcp_release_queue_work(struct work_struct *w)
        if (queue->hdr_digest || queue->data_digest)
                nvmet_tcp_free_crypto(queue);
        ida_free(&nvmet_tcp_queue_ida, queue->idx);
-       page = virt_to_head_page(queue->pf_cache.va);
-       __page_frag_cache_drain(page, queue->pf_cache.pagecnt_bias);
+       page_frag_cache_drain(&queue->pf_cache);
        kfree(queue);
 }
 
index 28aea17fa59b524f29d62b95d63929d021f6175b..6cef1c24118033b1ac18af348d742d4519a0e677 100644 (file)
@@ -311,6 +311,7 @@ extern void __free_pages(struct page *page, unsigned int order);
 extern void free_pages(unsigned long addr, unsigned int order);
 
 struct page_frag_cache;
+void page_frag_cache_drain(struct page_frag_cache *nc);
 extern void __page_frag_cache_drain(struct page *page, unsigned int count);
 void *__page_frag_alloc_align(struct page_frag_cache *nc, unsigned int fragsz,
                              gfp_t gfp_mask, unsigned int align_mask);
index 636145c29f703a19507403d59460b3c06b363fc9..06aa1ebbd21c62c048d23e84e1cb6ab98172e077 100644 (file)
@@ -4699,6 +4699,16 @@ static struct page *__page_frag_cache_refill(struct page_frag_cache *nc,
        return page;
 }
 
+void page_frag_cache_drain(struct page_frag_cache *nc)
+{
+       if (!nc->va)
+               return;
+
+       __page_frag_cache_drain(virt_to_head_page(nc->va), nc->pagecnt_bias);
+       nc->va = NULL;
+}
+EXPORT_SYMBOL(page_frag_cache_drain);
+
 void __page_frag_cache_drain(struct page *page, unsigned int count)
 {
        VM_BUG_ON_PAGE(page_ref_count(page) == 0, page);