page_pool: make sure struct device is stable
authorJesper Dangaard Brouer <brouer@redhat.com>
Tue, 18 Jun 2019 13:06:08 +0000 (15:06 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 19 Jun 2019 15:23:13 +0000 (11:23 -0400)
For DMA mapping use-case the page_pool keeps a pointer
to the struct device, which is used in DMA map/unmap calls.

For our in-flight handling, we also need to make sure that
the struct device have not disappeared.  This is assured
via using get_device/put_device API.

Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
Reported-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/page_pool.c

index f55ab055d543de60f567a38f0de1faaeb3de2c26..b366f59885c1ce1ce65288091de6f82e959273e8 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/device.h>
 
 #include <net/page_pool.h>
 #include <linux/dma-direction.h>
@@ -48,6 +49,9 @@ static int page_pool_init(struct page_pool *pool,
 
        atomic_set(&pool->pages_state_release_cnt, 0);
 
+       if (pool->p.flags & PP_FLAG_DMA_MAP)
+               get_device(pool->p.dev);
+
        return 0;
 }
 
@@ -360,6 +364,10 @@ void __page_pool_free(struct page_pool *pool)
                __warn_in_flight(pool);
 
        ptr_ring_cleanup(&pool->ring, NULL);
+
+       if (pool->p.flags & PP_FLAG_DMA_MAP)
+               put_device(pool->p.dev);
+
        kfree(pool);
 }
 EXPORT_SYMBOL(__page_pool_free);