--- /dev/null
+From cc82b3dcc6a8fa259fbda12ab00d6fc00908a49e Mon Sep 17 00:00:00 2001
+From: Yiyang Chen <cyyzero16@gmail.com>
+Date: Mon, 30 Mar 2026 03:00:41 +0800
+Subject: tools/accounting: handle truncated taskstats netlink messages
+
+From: Yiyang Chen <cyyzero16@gmail.com>
+
+commit cc82b3dcc6a8fa259fbda12ab00d6fc00908a49e upstream.
+
+procacct and getdelays use a fixed receive buffer for taskstats generic
+netlink messages. A multi-threaded process exit can emit a single
+PID+TGID notification large enough to exceed that buffer on newer kernels.
+
+Switch to recvmsg() so MSG_TRUNC is detected explicitly, increase the
+message buffer size, and report truncated datagrams clearly instead of
+misparsing them as fatal netlink errors.
+
+Also print the taskstats version in debug output to make version
+mismatches easier to diagnose while inspecting taskstats traffic.
+
+Link: https://lkml.kernel.org/r/520308bb4cbbaf8dc2c7296b5f60f11e12fb30a5.1774810498.git.cyyzero16@gmail.com
+Signed-off-by: Yiyang Chen <cyyzero16@gmail.com>
+Cc: Balbir Singh <bsingharora@gmail.com>
+Cc: Dr. Thomas Orgis <thomas.orgis@uni-hamburg.de>
+Cc: Fan Yu <fan.yu9@zte.com.cn>
+Cc: Wang Yaxin <wang.yaxin@zte.com.cn>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/accounting/getdelays.c | 41 +++++++++++++++++++++++++++++++++++++----
+ tools/accounting/procacct.c | 40 ++++++++++++++++++++++++++++++++++++----
+ 2 files changed, 73 insertions(+), 8 deletions(-)
+
+--- a/tools/accounting/getdelays.c
++++ b/tools/accounting/getdelays.c
+@@ -59,7 +59,7 @@ int print_task_context_switch_counts;
+ }
+
+ /* Maximum size of response requested or message sent */
+-#define MAX_MSG_SIZE 1024
++#define MAX_MSG_SIZE 2048
+ /* Maximum number of cpus expected to be specified in a cpumask */
+ #define MAX_CPUS 32
+
+@@ -114,6 +114,32 @@ error:
+ return -1;
+ }
+
++static int recv_taskstats_msg(int sd, struct msgtemplate *msg)
++{
++ struct sockaddr_nl nladdr;
++ struct iovec iov = {
++ .iov_base = msg,
++ .iov_len = sizeof(*msg),
++ };
++ struct msghdr hdr = {
++ .msg_name = &nladdr,
++ .msg_namelen = sizeof(nladdr),
++ .msg_iov = &iov,
++ .msg_iovlen = 1,
++ };
++ int ret;
++
++ ret = recvmsg(sd, &hdr, 0);
++ if (ret < 0)
++ return -1;
++ if (hdr.msg_flags & MSG_TRUNC) {
++ errno = EMSGSIZE;
++ return -1;
++ }
++
++ return ret;
++}
++
+
+ static int send_cmd(int sd, __u16 nlmsg_type, __u32 nlmsg_pid,
+ __u8 genl_cmd, __u16 nla_type,
+@@ -459,12 +485,16 @@ int main(int argc, char *argv[])
+ }
+
+ do {
+- rep_len = recv(nl_sd, &msg, sizeof(msg), 0);
++ rep_len = recv_taskstats_msg(nl_sd, &msg);
+ PRINTF("received %d bytes\n", rep_len);
+
+ if (rep_len < 0) {
+- fprintf(stderr, "nonfatal reply error: errno %d\n",
+- errno);
++ if (errno == EMSGSIZE)
++ fprintf(stderr,
++ "dropped truncated taskstats netlink message, please increase MAX_MSG_SIZE\n");
++ else
++ fprintf(stderr, "nonfatal reply error: errno %d\n",
++ errno);
+ continue;
+ }
+ if (msg.n.nlmsg_type == NLMSG_ERROR ||
+@@ -506,6 +536,9 @@ int main(int argc, char *argv[])
+ printf("TGID\t%d\n", rtid);
+ break;
+ case TASKSTATS_TYPE_STATS:
++ PRINTF("version %u\n",
++ ((struct taskstats *)
++ NLA_DATA(na))->version);
+ if (print_delays)
+ print_delayacct((struct taskstats *) NLA_DATA(na));
+ if (print_io_accounting)
+--- a/tools/accounting/procacct.c
++++ b/tools/accounting/procacct.c
+@@ -71,7 +71,7 @@ int print_task_context_switch_counts;
+ }
+
+ /* Maximum size of response requested or message sent */
+-#define MAX_MSG_SIZE 1024
++#define MAX_MSG_SIZE 2048
+ /* Maximum number of cpus expected to be specified in a cpumask */
+ #define MAX_CPUS 32
+
+@@ -121,6 +121,32 @@ error:
+ return -1;
+ }
+
++static int recv_taskstats_msg(int sd, struct msgtemplate *msg)
++{
++ struct sockaddr_nl nladdr;
++ struct iovec iov = {
++ .iov_base = msg,
++ .iov_len = sizeof(*msg),
++ };
++ struct msghdr hdr = {
++ .msg_name = &nladdr,
++ .msg_namelen = sizeof(nladdr),
++ .msg_iov = &iov,
++ .msg_iovlen = 1,
++ };
++ int ret;
++
++ ret = recvmsg(sd, &hdr, 0);
++ if (ret < 0)
++ return -1;
++ if (hdr.msg_flags & MSG_TRUNC) {
++ errno = EMSGSIZE;
++ return -1;
++ }
++
++ return ret;
++}
++
+
+ static int send_cmd(int sd, __u16 nlmsg_type, __u32 nlmsg_pid,
+ __u8 genl_cmd, __u16 nla_type,
+@@ -239,6 +265,8 @@ void handle_aggr(int mother, struct nlat
+ PRINTF("TGID\t%d\n", rtid);
+ break;
+ case TASKSTATS_TYPE_STATS:
++ PRINTF("version %u\n",
++ ((struct taskstats *)NLA_DATA(na))->version);
+ if (mother == TASKSTATS_TYPE_AGGR_PID)
+ print_procacct((struct taskstats *) NLA_DATA(na));
+ if (fd) {
+@@ -353,12 +381,16 @@ int main(int argc, char *argv[])
+ }
+
+ do {
+- rep_len = recv(nl_sd, &msg, sizeof(msg), 0);
++ rep_len = recv_taskstats_msg(nl_sd, &msg);
+ PRINTF("received %d bytes\n", rep_len);
+
+ if (rep_len < 0) {
+- fprintf(stderr, "nonfatal reply error: errno %d\n",
+- errno);
++ if (errno == EMSGSIZE)
++ fprintf(stderr,
++ "dropped truncated taskstats netlink message, please increase MAX_MSG_SIZE\n");
++ else
++ fprintf(stderr, "nonfatal reply error: errno %d\n",
++ errno);
+ continue;
+ }
+ if (msg.n.nlmsg_type == NLMSG_ERROR ||