git: 4daea938130b - main - Lock proctree in around fill_kinfo_proc().

Konstantin Belousov kib at FreeBSD.org
Sun Jan 10 02:42:00 UTC 2021


The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=4daea938130b4a219e01d678e9499f0bdb715f82

commit 4daea938130b4a219e01d678e9499f0bdb715f82
Author:     Konstantin Belousov <kib at FreeBSD.org>
AuthorDate: 2020-12-31 22:29:40 +0000
Commit:     Konstantin Belousov <kib at FreeBSD.org>
CommitDate: 2021-01-10 02:41:20 +0000

    Lock proctree in around fill_kinfo_proc().
    
    Proctree lock is needed for correct calculation and collection of the
    job-control related data in kinfo_proc.  There was even an XXX comment
    about it.
    
    Satisfy locking and lock ordering requirements by taking proctree lock
    around pass over each bucket in proc_iterate(), and in sysctl_kern_proc()
    and note_procstat_proc() for individual process reporting.
    
    Reviewed by:    jilles
    Tested by:      pho
    MFC after:      2 weeks
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D27871
---
 sys/kern/imgact_elf.c | 2 ++
 sys/kern/kern_proc.c  | 5 +++++
 2 files changed, 7 insertions(+)

diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index f6482bfcfb21..4f5d5a9a0736 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -2386,8 +2386,10 @@ __elfN(note_procstat_proc)(void *arg, struct sbuf *sb, size_t *sizep)
 		KASSERT(*sizep == size, ("invalid size"));
 		structsize = sizeof(elf_kinfo_proc_t);
 		sbuf_bcat(sb, &structsize, sizeof(structsize));
+		sx_slock(&proctree_lock);
 		PROC_LOCK(p);
 		kern_proc_out(p, sb, ELF_KERN_PROC_MASK);
+		sx_sunlock(&proctree_lock);
 	}
 	*sizep = size;
 }
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index fab1df795799..c63d136a3046 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -1653,6 +1653,7 @@ proc_iterate(int (*cb)(struct proc *, void *), void *cbarg)
 	int error, i, j;
 
 	for (i = 0; i < pidhashlock + 1; i++) {
+		sx_slock(&proctree_lock);
 		sx_slock(&pidhashtbl_lock[i]);
 		for (j = i; j <= pidhash; j += pidhashlock + 1) {
 			LIST_FOREACH(p, &pidhashtbl[j], p_hash) {
@@ -1662,11 +1663,13 @@ proc_iterate(int (*cb)(struct proc *, void *), void *cbarg)
 				PROC_LOCK_ASSERT(p, MA_NOTOWNED);
 				if (error != 0) {
 					sx_sunlock(&pidhashtbl_lock[i]);
+					sx_sunlock(&proctree_lock);
 					return (error);
 				}
 			}
 		}
 		sx_sunlock(&pidhashtbl_lock[i]);
+		sx_sunlock(&proctree_lock);
 	}
 	return (0);
 }
@@ -1792,9 +1795,11 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
 		error = sysctl_wire_old_buffer(req, 0);
 		if (error)
 			return (error);
+		sx_slock(&proctree_lock);
 		error = pget((pid_t)name[0], PGET_CANSEE, &p);
 		if (error == 0)
 			error = sysctl_out_proc(p, req, flags);
+		sx_sunlock(&proctree_lock);
 		return (error);
 	}
 


More information about the dev-commits-src-all mailing list