pid: Implement PIDTYPE_TGID
authorEric W. Biederman <ebiederm@xmission.com>
Sun, 4 Jun 2017 09:32:13 +0000 (04:32 -0500)
committerEric W. Biederman <ebiederm@xmission.com>
Sat, 21 Jul 2018 15:43:12 +0000 (10:43 -0500)
Everywhere except in the pid array we distinguish between a tasks pid and
a tasks tgid (thread group id).  Even in the enumeration we want that
distinction sometimes so we have added __PIDTYPE_TGID.  With leader_pid
we almost have an implementation of PIDTYPE_TGID in struct signal_struct.

Add PIDTYPE_TGID as a first class member of the pid_type enumeration and
into the pids array.  Then remove the __PIDTYPE_TGID special case and the
leader_pid in signal_struct.

The net size increase is just an extra pointer added to struct pid and
an extra pair of pointers of an hlist_node added to task_struct.

The effect on code maintenance is the removal of a number of special
cases today and the potential to remove many more special cases as
PIDTYPE_TGID gets used to it's fullest.  The long term potential
is allowing zombie thread group leaders to exit, which will remove
a lot more special cases in the code.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
14 files changed:
arch/ia64/kernel/asm-offsets.c
arch/ia64/kernel/fsys.S
arch/s390/kernel/perf_cpum_sf.c
fs/exec.c
include/linux/pid.h
include/linux/sched.h
include/linux/sched/signal.h
init/init_task.c
kernel/events/core.c
kernel/exit.c
kernel/fork.c
kernel/pid.c
kernel/time/itimer.c
kernel/time/posix-cpu-timers.c

index c1f8a57855af746ff375f3b7af9d630339075194..00e8e2a1eb19c304477cceb8af2f3b4c244132d3 100644 (file)
@@ -67,7 +67,7 @@ void foo(void)
        DEFINE(IA64_SIGNAL_GROUP_STOP_COUNT_OFFSET,offsetof (struct signal_struct,
                                                             group_stop_count));
        DEFINE(IA64_SIGNAL_SHARED_PENDING_OFFSET,offsetof (struct signal_struct, shared_pending));
-       DEFINE(IA64_SIGNAL_LEADER_PID_OFFSET, offsetof (struct signal_struct, leader_pid));
+       DEFINE(IA64_SIGNAL_PIDS_TGID_OFFSET, offsetof (struct signal_struct, pids[PIDTYPE_TGID]));
 
        BLANK();
 
index e85ebdac678b29018488b7a55c2a2372d3121e8e..d80c99a5f55dd105813846399c5589444a5c70b1 100644 (file)
@@ -68,10 +68,10 @@ ENTRY(fsys_getpid)
        add r9=TI_FLAGS+IA64_TASK_SIZE,r16
        ;;
        ld4 r9=[r9]
-       add r17=IA64_SIGNAL_LEADER_PID_OFFSET,r17
+       add r17=IA64_SIGNAL_PIDS_TGID_OFFSET,r17
        ;;
        and r9=TIF_ALLWORK_MASK,r9
-       ld8 r17=[r17]                           // r17 = current->signal->leader_pid
+       ld8 r17=[r17]                           // r17 = current->signal->pids[PIDTYPE_TGID]
        ;;
        add r8=IA64_PID_LEVEL_OFFSET,r17
        ;;
index 0292d68e7dded707496b7090c9b2d7377aab8b2b..ca0b7ae894bbaa3c0cd0b8600aa71cfbb3e53332 100644 (file)
@@ -665,7 +665,7 @@ static void cpumsf_output_event_pid(struct perf_event *event,
                goto out;
 
        /* Update the process ID (see also kernel/events/core.c) */
-       data->tid_entry.pid = cpumsf_pid_type(event, pid, __PIDTYPE_TGID);
+       data->tid_entry.pid = cpumsf_pid_type(event, pid, PIDTYPE_TGID);
        data->tid_entry.tid = cpumsf_pid_type(event, pid, PIDTYPE_PID);
 
        perf_output_sample(&handle, &header, data, event);
index 2d4e0075bd2457c83f9109d5a29365de61658840..79a11fbded7a5e562f10e829f0ad5a5675168d0a 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1146,6 +1146,7 @@ static int de_thread(struct task_struct *tsk)
                 */
                tsk->pid = leader->pid;
                change_pid(tsk, PIDTYPE_PID, task_pid(leader));
+               transfer_pid(leader, tsk, PIDTYPE_TGID);
                transfer_pid(leader, tsk, PIDTYPE_PGID);
                transfer_pid(leader, tsk, PIDTYPE_SID);
 
index 3d4c504dcc8c32e4d3721a5b53e96c0ae3cca0fd..14a9a39da9c77eab3fa21cb05e2b30206ed526d9 100644 (file)
@@ -7,11 +7,10 @@
 enum pid_type
 {
        PIDTYPE_PID,
+       PIDTYPE_TGID,
        PIDTYPE_PGID,
        PIDTYPE_SID,
        PIDTYPE_MAX,
-       /* only valid to __task_pid_nr_ns() */
-       __PIDTYPE_TGID
 };
 
 /*
index 445bdf5b1f643da8b3487dd33c947d39a98c3c2a..06b4e3bda93ab6f829050a6a85b9d39bba150ce0 100644 (file)
@@ -1275,12 +1275,12 @@ static inline pid_t task_session_vnr(struct task_struct *tsk)
 
 static inline pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
 {
-       return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, ns);
+       return __task_pid_nr_ns(tsk, PIDTYPE_TGID, ns);
 }
 
 static inline pid_t task_tgid_vnr(struct task_struct *tsk)
 {
-       return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, NULL);
+       return __task_pid_nr_ns(tsk, PIDTYPE_TGID, NULL);
 }
 
 static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns)
index 2dcded16eb1ec757ed3ea993c154005b6b74400c..ee30a5ba475f36ac2c74ba74da0af29d07e6b220 100644 (file)
@@ -147,7 +147,6 @@ struct signal_struct {
 #endif
 
        /* PID/PID hash table linkage. */
-       struct pid *leader_pid;
        struct pid *pids[PIDTYPE_MAX];
 
 #ifdef CONFIG_NO_HZ_FULL
@@ -571,7 +570,7 @@ struct pid *task_pid_type(struct task_struct *task, enum pid_type type)
 
 static inline struct pid *task_tgid(struct task_struct *task)
 {
-       return task->signal->leader_pid;
+       return task->signal->pids[PIDTYPE_TGID];
 }
 
 /*
@@ -607,7 +606,7 @@ static inline bool thread_group_leader(struct task_struct *p)
  */
 static inline bool has_group_leader_pid(struct task_struct *p)
 {
-       return task_pid(p) == p->signal->leader_pid;
+       return task_pid(p) == task_tgid(p);
 }
 
 static inline
index db12a61259f16d45c83e3b6d682da210a083c942..4f97846256d7c5e967b77591ec246ad5bc4c36a2 100644 (file)
@@ -33,9 +33,9 @@ static struct signal_struct init_signals = {
        },
 #endif
        INIT_CPU_TIMERS(init_signals)
-       .leader_pid = &init_struct_pid,
        .pids = {
                [PIDTYPE_PID]   = &init_struct_pid,
+               [PIDTYPE_TGID]  = &init_struct_pid,
                [PIDTYPE_PGID]  = &init_struct_pid,
                [PIDTYPE_SID]   = &init_struct_pid,
        },
index 80cca2b30c4fe02c1baca59b08c0cae158a7368e..9025b1796ca802256316d9f296a986bd52f2b37e 100644 (file)
@@ -1334,7 +1334,7 @@ static u32 perf_event_pid_type(struct perf_event *event, struct task_struct *p,
 
 static u32 perf_event_pid(struct perf_event *event, struct task_struct *p)
 {
-       return perf_event_pid_type(event, p, __PIDTYPE_TGID);
+       return perf_event_pid_type(event, p, PIDTYPE_TGID);
 }
 
 static u32 perf_event_tid(struct perf_event *event, struct task_struct *p)
index 16432428fc6c5c004add4fab6fc89e4c3a485f0a..25582b4429550c4643d5e0f8cde192268c350e50 100644 (file)
@@ -73,6 +73,7 @@ static void __unhash_process(struct task_struct *p, bool group_dead)
        nr_threads--;
        detach_pid(p, PIDTYPE_PID);
        if (group_dead) {
+               detach_pid(p, PIDTYPE_TGID);
                detach_pid(p, PIDTYPE_PGID);
                detach_pid(p, PIDTYPE_SID);
 
index d2952162399b7b860ed7dc2c67b230a95e8c14f8..cc5be0d01ce6a74147d91bafbd8223f513b40760 100644 (file)
@@ -1946,6 +1946,7 @@ static __latent_entropy struct task_struct *copy_process(
 
                init_task_pid(p, PIDTYPE_PID, pid);
                if (thread_group_leader(p)) {
+                       init_task_pid(p, PIDTYPE_TGID, pid);
                        init_task_pid(p, PIDTYPE_PGID, task_pgrp(current));
                        init_task_pid(p, PIDTYPE_SID, task_session(current));
 
@@ -1954,7 +1955,6 @@ static __latent_entropy struct task_struct *copy_process(
                                p->signal->flags |= SIGNAL_UNKILLABLE;
                        }
 
-                       p->signal->leader_pid = pid;
                        p->signal->tty = tty_kref_get(current->signal->tty);
                        /*
                         * Inherit has_child_subreaper flag under the same
@@ -1965,6 +1965,7 @@ static __latent_entropy struct task_struct *copy_process(
                                                         p->real_parent->signal->is_child_subreaper;
                        list_add_tail(&p->sibling, &p->real_parent->children);
                        list_add_tail_rcu(&p->tasks, &init_task.tasks);
+                       attach_pid(p, PIDTYPE_TGID);
                        attach_pid(p, PIDTYPE_PGID);
                        attach_pid(p, PIDTYPE_SID);
                        __this_cpu_inc(process_counts);
index f8486d2e2346809af2e0e375570d8edaa9e1454b..de1cfc4f75a2eb8df16e3d1018122226a1a30f14 100644 (file)
@@ -269,8 +269,6 @@ static struct pid **task_pid_ptr(struct task_struct *task, enum pid_type type)
 {
        return (type == PIDTYPE_PID) ?
                &task->thread_pid :
-               (type == __PIDTYPE_TGID) ?
-               &task->signal->leader_pid :
                &task->signal->pids[type];
 }
 
index f26acef5d7b485ad397c21bb5466f0a332006087..9a65713c83093f343466bd4ed0c5435d4077309c 100644 (file)
@@ -139,9 +139,10 @@ enum hrtimer_restart it_real_fn(struct hrtimer *timer)
 {
        struct signal_struct *sig =
                container_of(timer, struct signal_struct, real_timer);
+       struct pid *leader_pid = sig->pids[PIDTYPE_TGID];
 
-       trace_itimer_expire(ITIMER_REAL, sig->leader_pid, 0);
-       kill_pid_info(SIGALRM, SEND_SIG_PRIV, sig->leader_pid);
+       trace_itimer_expire(ITIMER_REAL, leader_pid, 0);
+       kill_pid_info(SIGALRM, SEND_SIG_PRIV, leader_pid);
 
        return HRTIMER_NORESTART;
 }
index 5a6251ac6f7acd183c35a51d9d55fb680fda64dd..40e6fae46cec51e7069659ab50a2c0932b1b6ce6 100644 (file)
@@ -895,7 +895,7 @@ static void check_cpu_itimer(struct task_struct *tsk, struct cpu_itimer *it,
 
                trace_itimer_expire(signo == SIGPROF ?
                                    ITIMER_PROF : ITIMER_VIRTUAL,
-                                   tsk->signal->leader_pid, cur_time);
+                                   task_tgid(tsk), cur_time);
                __group_send_sig_info(signo, SEND_SIG_PRIV, tsk);
        }