From patchwork Sat Nov 20 11:28:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yafang Shao X-Patchwork-Id: 12630347 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2F81FC433F5 for ; Sat, 20 Nov 2021 11:32:39 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 852DB6B007E; Sat, 20 Nov 2021 06:29:17 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 8012E6B0080; Sat, 20 Nov 2021 06:29:17 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 6A1CE6B0081; Sat, 20 Nov 2021 06:29:17 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0133.hostedemail.com [216.40.44.133]) by kanga.kvack.org (Postfix) with ESMTP id 5D5316B007E for ; Sat, 20 Nov 2021 06:29:17 -0500 (EST) Received: from smtpin01.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay02.hostedemail.com (Postfix) with ESMTP id 22F9B8CE3E for ; Sat, 20 Nov 2021 11:29:07 +0000 (UTC) X-FDA: 78829087176.01.7372085 Received: from mail-pj1-f46.google.com (mail-pj1-f46.google.com [209.85.216.46]) by imf13.hostedemail.com (Postfix) with ESMTP id 304DE10529B3 for ; Sat, 20 Nov 2021 11:29:05 +0000 (UTC) Received: by mail-pj1-f46.google.com with SMTP id j5-20020a17090a318500b001a6c749e697so10494696pjb.1 for ; Sat, 20 Nov 2021 03:29:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=uNX5FE2tZkxpuuqDEFiMRnO2iBatJ2sCTSVf95PnGcE=; b=c8gue+ynpuXN2yi3q0IDO2Y0JAfwSXqOX2jol0f2ra5ky3xAAhMluLSC5QUOwOkfN3 BfB2rLij2g0IAv9NWAhXCEcf0qO/IdSBiv9ikhP43imiqp/ooKm9FcoqgM9oW9zXUyFU 00v9F1uJuTUT+05/cy5XIYNn/RiSoLzkc3cREnwRtWgGZ6+R/N0kYEllnUsCPVm3yYCu FVwB4o0Mr96okvlTxxszIycaxnz5ti8XfkGiTtSSJePuj0SzfgQTnmb/WY7EtIiMaH4H /ei6d73j1KfhcT42VuFTqFoQMgcuByIvoE2bIvfzewbsW7/W3yHx/ahxCWfGSEnXnEf/ 7+6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=uNX5FE2tZkxpuuqDEFiMRnO2iBatJ2sCTSVf95PnGcE=; b=j/xXh9qx2E5c4gZiWjnV/m54JgJgSJh2j3pO4u0dddfOOI1//kYGiiW1C2pCGgcrw5 JgmxgM3Sa5s0QYNBhHxRnL8KTGPw4f8M5nqhbL7M32aZhlr0mfyzKV/jqrSUJYfkDHMO Qpvq541+DxchnqhmhaqIWBu4nAt9v9EPrgmjzQecFX/X1TJyi7J6LkdPgN3K3eor3WLp h8vAqED8zAUc2InQghbmBlxhJ7ohXuoK+nXI02NJQuLBE/rAngo6rBvGDq9bXLf3gyit eYksopbuCxo9SkQ11m8yQeJIjy0KitdDgx5bLO8nVZsoCaCemgWPZRaVRe03EgehIvXu z2fQ== X-Gm-Message-State: AOAM532hHHsQsZuLOXifZYx8GSix2qtO8aoVGkEHD8uak1xxBITzaQS8 lBE2v3/EvLtIjYGWTffLXMDqSxR5sK2SZNEpZAk= X-Google-Smtp-Source: ABdhPJzCRsH8UL7H3bVFjOBc9LDXDnX2Dy3UE5TX9gb0bv/UzEO6CZxyldqc+7CjJu3BgBtksGH2zw== X-Received: by 2002:a17:90a:ab17:: with SMTP id m23mr9412621pjq.194.1637407745940; Sat, 20 Nov 2021 03:29:05 -0800 (PST) Received: from vultr.guest ([66.42.104.82]) by smtp.gmail.com with ESMTPSA id g21sm2851745pfc.95.2021.11.20.03.29.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 20 Nov 2021 03:29:05 -0800 (PST) From: Yafang Shao To: akpm@linux-foundation.org Cc: netdev@vger.kernel.org, bpf@vger.kernel.org, linux-perf-users@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, oliver.sang@intel.com, lkp@intel.com, Yafang Shao , Petr Mladek , Steven Rostedt , Mathieu Desnoyers , Arnaldo Carvalho de Melo , Alexei Starovoitov , Andrii Nakryiko , Michal Miroslaw , Peter Zijlstra , Matthew Wilcox , David Hildenbrand , Al Viro , Kees Cook Subject: [PATCH v2] kthread: dynamically allocate memory to store kthread's full name Date: Sat, 20 Nov 2021 11:28:50 +0000 Message-Id: <20211120112850.46047-1-laoar.shao@gmail.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 X-Stat-Signature: wdbzpepb3u516dxayzcesmfnfmmg7c5t Authentication-Results: imf13.hostedemail.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=c8gue+yn; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (imf13.hostedemail.com: domain of laoar.shao@gmail.com designates 209.85.216.46 as permitted sender) smtp.mailfrom=laoar.shao@gmail.com X-Rspamd-Server: rspam03 X-Rspamd-Queue-Id: 304DE10529B3 X-HE-Tag: 1637407745-772878 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: When I was implementing a new per-cpu kthread cfs_migration, I found the comm of it "cfs_migration/%u" is truncated due to the limitation of TASK_COMM_LEN. For example, the comm of the percpu thread on CPU10~19 are all with the same name "cfs_migration/1", which will confuse the user. This issue is not critical, because we can get the corresponding CPU from the task's Cpus_allowed. But for kthreads correspoinding to other hardware devices, it is not easy to get the detailed device info from task comm, for example, jbd2/nvme0n1p2- xfs-reclaim/sdf Currently there are so many truncated kthreads: rcu_tasks_kthre rcu_tasks_rude_ rcu_tasks_trace poll_mpt3sas0_s ext4-rsv-conver xfs-reclaim/sd{a, b, c, ...} xfs-blockgc/sd{a, b, c, ...} xfs-inodegc/sd{a, b, c, ...} audit_send_repl ecryptfs-kthrea vfio-irqfd-clea jbd2/nvme0n1p2- ... We can shorten these names to work around this problem, but it may be not applied to all of the truncated kthreads. Take 'jbd2/nvme0n1p2-' for example, it is a nice name, and it is not a good idea to shorten it. One possible way to fix this issue is extending the task comm size, but as task->comm is used in lots of places, that may cause some potential buffer overflows. Another more conservative approach is introducing a new pointer to store kthread's full name if it is truncated, which won't introduce too much overhead as it is in the non-critical path. Finally we make a dicision to use the second approach. See also the discussions in this thread: https://lore.kernel.org/lkml/20211101060419.4682-1-laoar.shao@gmail.com/ After this change, the full name of these truncated kthreads will be displayed via /proc/[pid]/comm: rcu_tasks_kthread rcu_tasks_rude_kthread rcu_tasks_trace_kthread poll_mpt3sas0_statu ext4-rsv-conversion xfs-reclaim/sdf1 xfs-blockgc/sdf1 xfs-inodegc/sdf1 audit_send_reply ecryptfs-kthread vfio-irqfd-cleanup jbd2/nvme0n1p2-8 Suggested-by: Petr Mladek Suggested-by: Steven Rostedt Signed-off-by: Yafang Shao Cc: Mathieu Desnoyers Cc: Arnaldo Carvalho de Melo Cc: Alexei Starovoitov Cc: Andrii Nakryiko Cc: Michal Miroslaw Cc: Peter Zijlstra Cc: Steven Rostedt Cc: Matthew Wilcox Cc: David Hildenbrand Cc: Al Viro Cc: Kees Cook Cc: Petr Mladek Reviewed-by: Petr Mladek Reviewed-by: David Hildenbrand --- Changes since v1: 1. leave it turncated when out of memory (Kees & Petr) 2. do null check in free_kthread_struct (Petr) --- fs/proc/array.c | 3 +++ include/linux/kthread.h | 1 + kernel/kthread.c | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/fs/proc/array.c b/fs/proc/array.c index ff869a66b34e..4321aa63835d 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -92,6 +92,7 @@ #include #include #include +#include #include #include "internal.h" @@ -102,6 +103,8 @@ void proc_task_name(struct seq_file *m, struct task_struct *p, bool escape) if (p->flags & PF_WQ_WORKER) wq_worker_comm(tcomm, sizeof(tcomm), p); + else if (p->flags & PF_KTHREAD) + get_kthread_comm(tcomm, sizeof(tcomm), p); else __get_task_comm(tcomm, sizeof(tcomm), p); diff --git a/include/linux/kthread.h b/include/linux/kthread.h index 346b0f269161..2a5c04494663 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h @@ -33,6 +33,7 @@ struct task_struct *kthread_create_on_cpu(int (*threadfn)(void *data), unsigned int cpu, const char *namefmt); +void get_kthread_comm(char *buf, size_t buf_size, struct task_struct *tsk); void set_kthread_struct(struct task_struct *p); void kthread_set_per_cpu(struct task_struct *k, int cpu); diff --git a/kernel/kthread.c b/kernel/kthread.c index 7113003fab63..a70cd5dc94e3 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -60,6 +60,8 @@ struct kthread { #ifdef CONFIG_BLK_CGROUP struct cgroup_subsys_state *blkcg_css; #endif + /* To store the full name if task comm is truncated. */ + char *full_name; }; enum KTHREAD_BITS { @@ -93,6 +95,18 @@ static inline struct kthread *__to_kthread(struct task_struct *p) return kthread; } +void get_kthread_comm(char *buf, size_t buf_size, struct task_struct *tsk) +{ + struct kthread *kthread = to_kthread(tsk); + + if (!kthread || !kthread->full_name) { + __get_task_comm(buf, buf_size, tsk); + return; + } + + strscpy_pad(buf, kthread->full_name, buf_size); +} + void set_kthread_struct(struct task_struct *p) { struct kthread *kthread; @@ -118,9 +132,13 @@ void free_kthread_struct(struct task_struct *k) * or if kmalloc() in kthread() failed. */ kthread = to_kthread(k); + if (!kthread) + return; + #ifdef CONFIG_BLK_CGROUP - WARN_ON_ONCE(kthread && kthread->blkcg_css); + WARN_ON_ONCE(kthread->blkcg_css); #endif + kfree(kthread->full_name); kfree(kthread); } @@ -406,12 +424,22 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data), task = create->result; if (!IS_ERR(task)) { char name[TASK_COMM_LEN]; + va_list aq; + int len; /* * task is already visible to other tasks, so updating * COMM must be protected. */ - vsnprintf(name, sizeof(name), namefmt, args); + va_copy(aq, args); + len = vsnprintf(name, sizeof(name), namefmt, aq); + va_end(aq); + if (len >= TASK_COMM_LEN) { + struct kthread *kthread = to_kthread(task); + + /* leave it truncated when out of memory. */ + kthread->full_name = kvasprintf(GFP_KERNEL, namefmt, args); + } set_task_comm(task, name); } kfree(create);