page_pool: add a lockdep check for recycling in hardirq
authorJakub Kicinski <kuba@kernel.org>
Fri, 4 Aug 2023 18:05:28 +0000 (20:05 +0200)
committerJakub Kicinski <kuba@kernel.org>
Mon, 7 Aug 2023 20:05:53 +0000 (13:05 -0700)
Page pool use in hardirq is prohibited, add debug checks
to catch misuses. IIRC we previously discussed using
DEBUG_NET_WARN_ON_ONCE() for this, but there were concerns
that people will have DEBUG_NET enabled in perf testing.
I don't think anyone enables lockdep in perf testing,
so use lockdep to avoid pushback and arguing :)

Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com>
Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
Link: https://lore.kernel.org/r/20230804180529.2483231-6-aleksander.lobakin@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/linux/lockdep.h
net/core/page_pool.c

index 310f859..dc2844b 100644 (file)
@@ -625,6 +625,12 @@ do {                                                                       \
        WARN_ON_ONCE(__lockdep_enabled && !this_cpu_read(hardirq_context)); \
 } while (0)
 
+#define lockdep_assert_no_hardirq()                                    \
+do {                                                                   \
+       WARN_ON_ONCE(__lockdep_enabled && (this_cpu_read(hardirq_context) || \
+                                          !this_cpu_read(hardirqs_enabled))); \
+} while (0)
+
 #define lockdep_assert_preemption_enabled()                            \
 do {                                                                   \
        WARN_ON_ONCE(IS_ENABLED(CONFIG_PREEMPT_COUNT)   &&              \
@@ -659,6 +665,7 @@ do {                                                                        \
 # define lockdep_assert_irqs_enabled() do { } while (0)
 # define lockdep_assert_irqs_disabled() do { } while (0)
 # define lockdep_assert_in_irq() do { } while (0)
+# define lockdep_assert_no_hardirq() do { } while (0)
 
 # define lockdep_assert_preemption_enabled() do { } while (0)
 # define lockdep_assert_preemption_disabled() do { } while (0)
index 03ad74d..77cb75e 100644 (file)
@@ -587,6 +587,8 @@ static __always_inline struct page *
 __page_pool_put_page(struct page_pool *pool, struct page *page,
                     unsigned int dma_sync_size, bool allow_direct)
 {
+       lockdep_assert_no_hardirq();
+
        /* This allocator is optimized for the XDP mode that uses
         * one-frame-per-page, but have fallbacks that act like the
         * regular page allocator APIs.