Re: [PATCH] bpf: task_group_seq_get_next: cleanup the usage of get/put_task_struct

From: Kui-Feng Lee
Date: Mon Aug 21 2023 - 16:38:54 EST




On 8/21/23 13:32, Kui-Feng Lee wrote:


On 8/21/23 13:03, Oleg Nesterov wrote:
get_pid_task() makes no sense, the code does put_task_struct() soon after.
Use find_task_by_pid_ns() instead of find_pid_ns + get_pid_task and kill
kill put_task_struct(), this allows to do get_task_struct() only once
before return.

While at it, kill the unnecessary "if (!pid)" check in the "if (!*tid)"
block, this matches the next usage of find_pid_ns() + get_pid_task() in
this function.

Signed-off-by: Oleg Nesterov <oleg@xxxxxxxxxx>
---
  kernel/bpf/task_iter.c | 12 ++----------
  1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/kernel/bpf/task_iter.c b/kernel/bpf/task_iter.c
index 4d1125108014..1589ec3faded 100644
--- a/kernel/bpf/task_iter.c
+++ b/kernel/bpf/task_iter.c
@@ -42,9 +42,6 @@ static struct task_struct *task_group_seq_get_next(struct bpf_iter_seq_task_comm
      if (!*tid) {
          /* The first time, the iterator calls this function. */
          pid = find_pid_ns(common->pid, common->ns);
-        if (!pid)
-            return NULL;
-
          task = get_pid_task(pid, PIDTYPE_TGID);
          if (!task)
              return NULL;
@@ -66,17 +63,12 @@ static struct task_struct *task_group_seq_get_next(struct bpf_iter_seq_task_comm
          return task;
      }
-    pid = find_pid_ns(common->pid_visiting, common->ns);
-    if (!pid)
-        return NULL;
-
-    task = get_pid_task(pid, PIDTYPE_PID);
+    task = find_task_by_pid_ns(common->pid_visiting, common->ns);
      if (!task)
          return NULL;
  retry:
      next_task = next_thread(task);
-    put_task_struct(task);

It called get_task_struct() against this task to hold a refcount at the
previous time calling this function. When will it release the refcount?


Oh! I missed the fact that the caller will handle it.


      saved_tid = *tid;
      *tid = __task_pid_nr_ns(next_task, PIDTYPE_PID, common->ns);
@@ -88,7 +80,6 @@ static struct task_struct *task_group_seq_get_next(struct bpf_iter_seq_task_comm
          return NULL;
      }
-    get_task_struct(next_task);
      common->pid_visiting = *tid;
      if (skip_if_dup_files && task->files == task->group_leader->files) {
@@ -96,6 +87,7 @@ static struct task_struct *task_group_seq_get_next(struct bpf_iter_seq_task_comm
          goto retry;
      }
+    get_task_struct(next_task);
      return next_task;
  }