On Mon, Nov 6, 2023 at 1:02 PM Stanislav Fomichev sdf@google.com wrote:
On 11/05, Mina Almasry wrote:
+static inline bool page_is_page_pool_iov(const struct page *page) +{
return (unsigned long)page & PP_DEVMEM;
+}
Speaking of bpf: one thing that might be problematic with this PP_DEVMEM bit is that it will make debugging with bpftrace a bit (more) complicated. If somebody were trying to get to that page_pool_iov from the frags, they will have to do the equivalent of page_is_page_pool_iov, but probably not a big deal? (thinking out loud)
Good point, but that doesn't only apply to bpf I think. I'm guessing even debugger drgn access to the bv_page in the frag will have trouble if it's actually accessing an iov with LSB set.
But this is not specific to this use for LSB pointer trick. I think all code that currently uses LSB pointer trick will have similar troubles. In this context my humble vote is that we get such big upside from reducing code churn that it's reasonable to tolerate such side effects.
I could alleviate some of the issues by teaching drgn to do the right thing for devmem/iovs... time permitting.
On Mon, Nov 6, 2023 at 3:49 PM David Ahern dsahern@kernel.org wrote:
On 11/5/23 7:44 PM, Mina Almasry wrote:
diff --git a/include/net/page_pool/helpers.h b/include/net/page_pool/helpers.h index 78cbb040af94..b93243c2a640 100644 --- a/include/net/page_pool/helpers.h +++ b/include/net/page_pool/helpers.h @@ -111,6 +112,45 @@ page_pool_iov_binding(const struct page_pool_iov *ppiov) return page_pool_iov_owner(ppiov)->binding; }
+static inline int page_pool_iov_refcount(const struct page_pool_iov *ppiov) +{
return refcount_read(&ppiov->refcount);
+}
+static inline void page_pool_iov_get_many(struct page_pool_iov *ppiov,
unsigned int count)
+{
refcount_add(count, &ppiov->refcount);
+}
+void __page_pool_iov_free(struct page_pool_iov *ppiov);
+static inline void page_pool_iov_put_many(struct page_pool_iov *ppiov,
unsigned int count)
+{
if (!refcount_sub_and_test(count, &ppiov->refcount))
return;
__page_pool_iov_free(ppiov);
+}
+/* page pool mm helpers */
+static inline bool page_is_page_pool_iov(const struct page *page) +{
return (unsigned long)page & PP_DEVMEM;
This is another one where the code can be more generic to not force a lot changes later. e.g., PP_CUSTOM or PP_NO_PAGE. Then io_uring use case with host memory can leverage the iov pool in a similar manner.
That does mean skb->devmem needs to be a flag on the page pool and not just assume iov == device memory.