From ddf142e5a817e3a260e5dedce0cd29db6fbaa010 Mon Sep 17 00:00:00 2001 From: Jong eon Park Date: Wed, 29 Nov 2023 16:50:44 +0900 Subject: [PATCH] ANDROID: netlink: add netlink poll and hooks In huge uevents generating system, especially for user apps who have small size of rcvbuf socket, it has been reported that netlink overrun happens quite frequently. Moreover, if there's no POLLERR (caused by this netlink overrun) handler in user apps, the system can almost be stucked by calling 'poll' repeatedly. Regarding this issue, I have sent a kernel netlink patch to linux maintainers and got replied that this is absolutely user app's problem, must not addressing kernel. Until Android team look into this issue and some modification comes out, we need kernel patch for temporary. To minimize the effect by this patch to the others who have never met this issue, I would like to just add netlink's dedicated poll and its hooks. Please refer to below v1/v2 patch links for history. v1: https://lore.kernel.org/netdev/20231110110002.7279f895@kernel.org/T/#t v2: https://lore.kernel.org/netdev/d599922fd89b3e61c7cf531a03ea8b81cbcb003e.camel@redhat.com/T/#t Bug: 300009377 Link: https://lore.kernel.org/netdev/d599922fd89b3e61c7cf531a03ea8b81cbcb003e.camel@redhat.com/T/#t Change-Id: I4f11399d61c10332ba05bac64cfa1e92bb111565 Signed-off-by: Jong eon Park --- drivers/android/vendor_hooks.c | 1 + include/trace/hooks/net.h | 7 +++++++ net/netlink/af_netlink.c | 14 ++++++++++++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 8425e8709b41..789fa7beea83 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -364,3 +364,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmc_blk_mq_rw_recovery); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sd_update_bus_speed_mode); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_slab_folio_alloced); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_kmalloc_large_alloced); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_netlink_poll); diff --git a/include/trace/hooks/net.h b/include/trace/hooks/net.h index 50988f672216..835943c31f3d 100644 --- a/include/trace/hooks/net.h +++ b/include/trace/hooks/net.h @@ -25,6 +25,13 @@ DECLARE_RESTRICTED_HOOK(android_rvh_sk_alloc, DECLARE_RESTRICTED_HOOK(android_rvh_sk_free, TP_PROTO(struct sock *sock), TP_ARGS(sock), 1); +struct poll_table_struct; +typedef struct poll_table_struct poll_table; +DECLARE_HOOK(android_vh_netlink_poll, + TP_PROTO(struct file *file, struct socket *sock, poll_table *wait, + __poll_t *mask), + TP_ARGS(file, sock, wait, mask)); + /* macro versions of hooks are no longer required */ #endif /* _TRACE_HOOK_NET_VH_H */ diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index cb833302270a..5b328a82ea70 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -71,7 +71,8 @@ #include #define CREATE_TRACE_POINTS #include - +#undef CREATE_TRACE_POINTS +#include #include "af_netlink.h" struct listeners { @@ -1966,6 +1967,15 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, return err ? : copied; } +static __poll_t netlink_poll(struct file *file, struct socket *sock, + poll_table *wait) +{ + __poll_t mask = datagram_poll(file, sock, wait); + + trace_android_vh_netlink_poll(file, sock, wait, &mask); + return mask; +} + static void netlink_data_ready(struct sock *sk) { BUG(); @@ -2766,7 +2776,7 @@ static const struct proto_ops netlink_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = netlink_getname, - .poll = datagram_poll, + .poll = netlink_poll, .ioctl = netlink_ioctl, .listen = sock_no_listen, .shutdown = sock_no_shutdown,