page_pool: make sure struct device is stable

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>
This commit is contained in:
Jesper Dangaard Brouer 2019-06-18 15:06:08 +02:00 committed by David S. Miller
parent 32c28f7e41
commit f71fec47c2

View File

@ -8,6 +8,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/device.h>
#include <net/page_pool.h> #include <net/page_pool.h>
#include <linux/dma-direction.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); atomic_set(&pool->pages_state_release_cnt, 0);
if (pool->p.flags & PP_FLAG_DMA_MAP)
get_device(pool->p.dev);
return 0; return 0;
} }
@ -360,6 +364,10 @@ void __page_pool_free(struct page_pool *pool)
__warn_in_flight(pool); __warn_in_flight(pool);
ptr_ring_cleanup(&pool->ring, NULL); ptr_ring_cleanup(&pool->ring, NULL);
if (pool->p.flags & PP_FLAG_DMA_MAP)
put_device(pool->p.dev);
kfree(pool); kfree(pool);
} }
EXPORT_SYMBOL(__page_pool_free); EXPORT_SYMBOL(__page_pool_free);