Page MenuHomeFreeBSD

D12773.id34280.diff
No OneTemporary

D12773.id34280.diff

Index: lib/libc/sys/Symbol.map
===================================================================
--- lib/libc/sys/Symbol.map
+++ lib/libc/sys/Symbol.map
@@ -554,6 +554,7 @@
__sys_extattr_set_link;
_extattrctl;
__sys_extattrctl;
+ __sys_fast_sigblock;
_fchdir;
__sys_fchdir;
_fchflags;
Index: libexec/rtld-elf/rtld.h
===================================================================
--- libexec/rtld-elf/rtld.h
+++ libexec/rtld-elf/rtld.h
@@ -360,6 +360,7 @@
extern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
extern Elf_Sym sym_zero; /* For resolving undefined weak refs. */
extern bool ld_bind_not;
+extern bool ld_fast_sigblock;
void dump_relocations(Obj_Entry *);
void dump_obj_relocations(Obj_Entry *);
Index: libexec/rtld-elf/rtld.c
===================================================================
--- libexec/rtld-elf/rtld.c
+++ libexec/rtld-elf/rtld.c
@@ -265,6 +265,7 @@
int tls_max_index = 1; /* Largest module index allocated */
bool ld_library_path_rpath = false;
+bool ld_fast_sigblock = false;
/*
* Globals for path names, and such
@@ -417,6 +418,10 @@
((unsigned char *)(void *)__stack_chk_guard)[3] = 255;
}
}
+ if (aux_info[AT_BSDFLAGS] != NULL) {
+ if ((aux_info[AT_BSDFLAGS]->a_un.a_val & ELF_BSDF_FASTSIGBLK) != 0)
+ ld_fast_sigblock = true;
+ }
trust = !issetugid();
Index: libexec/rtld-elf/rtld_lock.c
===================================================================
--- libexec/rtld-elf/rtld_lock.c
+++ libexec/rtld-elf/rtld_lock.c
@@ -43,6 +43,7 @@
*/
#include <sys/param.h>
+#include <sys/signalvar.h>
#include <signal.h>
#include <stdlib.h>
#include <time.h>
@@ -65,6 +66,7 @@
static sigset_t fullsigmask, oldsigmask;
static int thread_flag, wnested;
+static uint32_t fsigblock;
static void *
def_lock_create(void)
@@ -114,6 +116,16 @@
; /* Spin */
}
+static void
+sig_fastunblock(void)
+{
+ uint32_t oldval;
+
+ oldval = atomic_fetchadd_32(&fsigblock, -FAST_SIGBLOCK_INC);
+ if (oldval == (FAST_SIGBLOCK_PEND | FAST_SIGBLOCK_INC))
+ __sys_fast_sigblock(FAST_SIGBLOCK_UNBLOCK, NULL);
+}
+
static void
def_wlock_acquire(void *lock)
{
@@ -121,14 +133,23 @@
sigset_t tmp_oldsigmask;
l = (Lock *)lock;
- for (;;) {
- sigprocmask(SIG_BLOCK, &fullsigmask, &tmp_oldsigmask);
- if (atomic_cmpset_acq_int(&l->lock, 0, WAFLAG))
- break;
- sigprocmask(SIG_SETMASK, &tmp_oldsigmask, NULL);
+ if (ld_fast_sigblock) {
+ for (;;) {
+ atomic_add_32(&fsigblock, FAST_SIGBLOCK_INC);
+ if (atomic_cmpset_acq_int(&l->lock, 0, WAFLAG))
+ break;
+ sig_fastunblock();
+ }
+ } else {
+ for (;;) {
+ sigprocmask(SIG_BLOCK, &fullsigmask, &tmp_oldsigmask);
+ if (atomic_cmpset_acq_int(&l->lock, 0, WAFLAG))
+ break;
+ sigprocmask(SIG_SETMASK, &tmp_oldsigmask, NULL);
+ }
+ if (atomic_fetchadd_int(&wnested, 1) == 0)
+ oldsigmask = tmp_oldsigmask;
}
- if (atomic_fetchadd_int(&wnested, 1) == 0)
- oldsigmask = tmp_oldsigmask;
}
static void
@@ -140,9 +161,10 @@
if ((l->lock & WAFLAG) == 0)
atomic_add_rel_int(&l->lock, -RC_INCR);
else {
- assert(wnested > 0);
atomic_add_rel_int(&l->lock, -WAFLAG);
- if (atomic_fetchadd_int(&wnested, -1) == 1)
+ if (ld_fast_sigblock)
+ sig_fastunblock();
+ else if (atomic_fetchadd_int(&wnested, -1) == 1)
sigprocmask(SIG_SETMASK, &oldsigmask, NULL);
}
}
@@ -295,19 +317,24 @@
memcpy(&lockinfo, &deflockinfo, sizeof(lockinfo));
_rtld_thread_init(NULL);
- /*
- * Construct a mask to block all signals except traps which might
- * conceivably be generated within the dynamic linker itself.
- */
- sigfillset(&fullsigmask);
- sigdelset(&fullsigmask, SIGILL);
- sigdelset(&fullsigmask, SIGTRAP);
- sigdelset(&fullsigmask, SIGABRT);
- sigdelset(&fullsigmask, SIGEMT);
- sigdelset(&fullsigmask, SIGFPE);
- sigdelset(&fullsigmask, SIGBUS);
- sigdelset(&fullsigmask, SIGSEGV);
- sigdelset(&fullsigmask, SIGSYS);
+ if (ld_fast_sigblock)
+ __sys_fast_sigblock(FAST_SIGBLOCK_SETPTR, &fsigblock);
+ else {
+ /*
+ * Construct a mask to block all signals except traps
+ * which might conceivably be generated within the
+ * dynamic linker itself.
+ */
+ sigfillset(&fullsigmask);
+ sigdelset(&fullsigmask, SIGILL);
+ sigdelset(&fullsigmask, SIGTRAP);
+ sigdelset(&fullsigmask, SIGABRT);
+ sigdelset(&fullsigmask, SIGEMT);
+ sigdelset(&fullsigmask, SIGFPE);
+ sigdelset(&fullsigmask, SIGBUS);
+ sigdelset(&fullsigmask, SIGSEGV);
+ sigdelset(&fullsigmask, SIGSYS);
+ }
}
/*
@@ -328,7 +355,10 @@
if (pli == NULL)
pli = &deflockinfo;
-
+ else if (ld_fast_sigblock) {
+ fsigblock = 0;
+ __sys_fast_sigblock(FAST_SIGBLOCK_UNSETPTR, NULL);
+ }
for (i = 0; i < RTLD_LOCK_CNT; i++)
if ((locks[i] = pli->lock_create()) == NULL)
Index: sys/arm/include/elf.h
===================================================================
--- sys/arm/include/elf.h
+++ sys/arm/include/elf.h
@@ -87,8 +87,9 @@
#define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */
#define AT_HWCAP 25 /* CPU feature flags. */
#define AT_HWCAP2 26 /* CPU feature flags 2. */
+#define AT_BSDFLAGS 27 /* ELF BSD Flags. */
-#define AT_COUNT 27 /* Count of defined aux entry types. */
+#define AT_COUNT 28 /* Count of defined aux entry types. */
#define R_ARM_COUNT 33 /* Count of defined relocation types. */
Index: sys/compat/freebsd32/syscalls.master
===================================================================
--- sys/compat/freebsd32/syscalls.master
+++ sys/compat/freebsd32/syscalls.master
@@ -1119,3 +1119,4 @@
struct kevent32 *eventlist, \
int nevents, \
const struct timespec32 *timeout); }
+561 AUE_NULL NOPROTO { int fast_sigblock(int cmd, uint32_t *ptr); }
Index: sys/kern/imgact_elf.c
===================================================================
--- sys/kern/imgact_elf.c
+++ sys/kern/imgact_elf.c
@@ -1135,6 +1135,7 @@
AUXARGS_ENTRY(pos, AT_HWCAP, *imgp->sysent->sv_hwcap);
if (imgp->sysent->sv_hwcap2 != NULL)
AUXARGS_ENTRY(pos, AT_HWCAP2, *imgp->sysent->sv_hwcap2);
+ AUXARGS_ENTRY(pos, AT_BSDFLAGS, ELF_BSDF_FASTSIGBLK);
AUXARGS_ENTRY(pos, AT_NULL, 0);
free(imgp->auxargs, M_TEMP);
Index: sys/kern/kern_exec.c
===================================================================
--- sys/kern/kern_exec.c
+++ sys/kern/kern_exec.c
@@ -1061,6 +1061,7 @@
int error;
struct proc *p = imgp->proc;
struct vmspace *vmspace = p->p_vmspace;
+ struct thread *td = curthread;
vm_object_t obj;
struct rlimit rlim_stack;
vm_offset_t sv_minuser, stack_addr;
@@ -1070,6 +1071,10 @@
imgp->vmspace_destroyed = 1;
imgp->sysent = sv;
+ td->td_pflags &= ~TDP_FAST_SIGBLOCK;
+ td->td_sigblock_ptr = NULL;
+ td->td_sigblock_val = 0;
+
/* May be called with Giant held */
EVENTHANDLER_INVOKE(process_exec, p, imgp);
Index: sys/kern/kern_fork.c
===================================================================
--- sys/kern/kern_fork.c
+++ sys/kern/kern_fork.c
@@ -600,7 +600,8 @@
* been preserved.
*/
p2->p_flag |= p1->p_flag & P_SUGID;
- td2->td_pflags |= (td->td_pflags & TDP_ALTSTACK) | TDP_FORKING;
+ td2->td_pflags |= (td->td_pflags & (TDP_ALTSTACK |
+ TDP_FAST_SIGBLOCK)) | TDP_FORKING;
SESS_LOCK(p1->p_session);
if (p1->p_session->s_ttyvp != NULL && p1->p_flag & P_CONTROLT)
p2->p_flag |= P_CONTROLT;
Index: sys/kern/kern_proc.c
===================================================================
--- sys/kern/kern_proc.c
+++ sys/kern/kern_proc.c
@@ -2881,6 +2881,77 @@
return (error);
}
+static int
+sysctl_kern_proc_fastsigblk(SYSCTL_HANDLER_ARGS)
+{
+ int *name = (int *)arg1;
+ u_int namelen = arg2;
+ pid_t pid;
+ struct proc *p;
+ struct thread *td1;
+ uintptr_t addr;
+#ifdef COMPAT_FREEBSD32
+ uint32_t addr32;
+#endif
+ int error;
+
+ if (namelen != 1 || req->newptr != NULL)
+ return (EINVAL);
+
+ pid = (pid_t)name[0];
+ error = pget(pid, PGET_HOLD | PGET_NOTWEXIT | PGET_CANDEBUG, &p);
+ if (error != 0)
+ return (error);
+
+ PROC_LOCK(p);
+#ifdef COMPAT_FREEBSD32
+ if (SV_CURPROC_FLAG(SV_ILP32)) {
+ if (!SV_PROC_FLAG(p, SV_ILP32)) {
+ error = EINVAL;
+ goto errlocked;
+ }
+ }
+#endif
+ if (pid <= PID_MAX) {
+ td1 = FIRST_THREAD_IN_PROC(p);
+ } else {
+ FOREACH_THREAD_IN_PROC(p, td1) {
+ if (td1->td_tid == pid)
+ break;
+ }
+ }
+ if (td1 == NULL) {
+ error = ESRCH;
+ goto errlocked;
+ }
+ /*
+ * The access to the private thread flags. It is fine as far
+ * as no out-of-thin-air values are read from td_pflags, and
+ * usermode read of the td_sigblock_ptr is racy inherently,
+ * since target process might have already changed it
+ * meantime.
+ */
+ if ((td1->td_pflags & TDP_FAST_SIGBLOCK) != 0)
+ addr = (uintptr_t)td1->td_sigblock_ptr;
+ else
+ error = ENOTTY;
+
+errlocked:
+ _PRELE(p);
+ PROC_UNLOCK(p);
+ if (error != 0)
+ return (error);
+
+#ifdef COMPAT_FREEBSD32
+ if (SV_CURPROC_FLAG(SV_ILP32)) {
+ addr32 = addr;
+ error = SYSCTL_OUT(req, &addr32, sizeof(addr32));
+ } else
+#endif
+ error = SYSCTL_OUT(req, &addr, sizeof(addr));
+ return (error);
+}
+
SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD, 0, "Process table");
SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLFLAG_RD|CTLTYPE_STRUCT|
@@ -2994,6 +3065,10 @@
CTLFLAG_MPSAFE, sysctl_kern_proc_sigtramp,
"Process signal trampoline location");
+static SYSCTL_NODE(_kern_proc, KERN_PROC_FASTSIGBLK, fastsigblk, CTLFLAG_RD |
+ CTLFLAG_ANYBODY | CTLFLAG_MPSAFE, sysctl_kern_proc_fastsigblk,
+ "Thread fast_sigblock address");
+
int allproc_gen;
/*
Index: sys/kern/kern_sig.c
===================================================================
--- sys/kern/kern_sig.c
+++ sys/kern/kern_sig.c
@@ -236,6 +236,7 @@
};
static void reschedule_signals(struct proc *p, sigset_t block, int flags);
+static sigset_t fastblock_mask;
static void
sigqueue_start(void)
@@ -246,6 +247,16 @@
p31b_setcfg(CTL_P1003_1B_REALTIME_SIGNALS, _POSIX_REALTIME_SIGNALS);
p31b_setcfg(CTL_P1003_1B_RTSIG_MAX, SIGRTMAX - SIGRTMIN + 1);
p31b_setcfg(CTL_P1003_1B_SIGQUEUE_MAX, max_pending_per_proc);
+ SIGFILLSET(fastblock_mask);
+ SIG_CANTMASK(fastblock_mask);
+ SIGDELSET(fastblock_mask, SIGILL);
+ SIGDELSET(fastblock_mask, SIGTRAP);
+ SIGDELSET(fastblock_mask, SIGABRT);
+ SIGDELSET(fastblock_mask, SIGEMT);
+ SIGDELSET(fastblock_mask, SIGFPE);
+ SIGDELSET(fastblock_mask, SIGBUS);
+ SIGDELSET(fastblock_mask, SIGSEGV);
+ SIGDELSET(fastblock_mask, SIGSYS);
}
ksiginfo_t *
@@ -2805,6 +2816,24 @@
SIG_STOPSIGMASK(sigpending);
if (SIGISEMPTY(sigpending)) /* no signal to send */
return (0);
+
+ /*
+ * Do fast sigblock if requested by usermode. Since
+ * we do know that there was a signal pending at this
+ * point, set the FAST_SIGBLOCK_PEND as indicator for
+ * usermode to perform a dummy call to
+ * FAST_SIGBLOCK_UNBLOCK, which causes immediate
+ * delivery of postponed pending signal.
+ */
+ if ((td->td_pflags & TDP_FAST_SIGBLOCK) != 0) {
+ if (td->td_sigblock_val != 0)
+ SIGSETNAND(sigpending, fastblock_mask);
+ if (SIGISEMPTY(sigpending)) {
+ td->td_pflags |= TDP_FAST_SIGPENDING;
+ return (0);
+ }
+ }
+
if ((p->p_flag & (P_TRACED | P_PPTRACE)) == P_TRACED &&
(p->p_flag2 & P2_PTRACE_FSTP) != 0 &&
SIGISMEMBER(sigpending, SIGSTOP)) {
@@ -3737,3 +3766,92 @@
return (ps->ps_refcnt > 1);
}
+
+int
+sys_fast_sigblock(struct thread *td, struct fast_sigblock_args *uap)
+{
+ struct proc *p;
+ int error;
+ uint32_t oldval;
+
+ error = 0;
+ switch (uap->cmd) {
+ case FAST_SIGBLOCK_SETPTR:
+ if ((td->td_pflags & TDP_FAST_SIGBLOCK) != 0)
+ error = EBUSY;
+ else if (((uintptr_t)(uap->ptr) & (sizeof(uint32_t) - 1)) != 0)
+ error = EINVAL;
+ else {
+ td->td_pflags |= TDP_FAST_SIGBLOCK;
+ td->td_sigblock_ptr = uap->ptr;
+ }
+ break;
+
+ case FAST_SIGBLOCK_UNBLOCK:
+ if ((td->td_pflags & TDP_FAST_SIGBLOCK) != 0) {
+ oldval = casuword32(td->td_sigblock_ptr,
+ FAST_SIGBLOCK_PEND, 0);
+ if (oldval == (uint32_t)-1)
+ error = EFAULT;
+ else if (oldval != FAST_SIGBLOCK_PEND)
+ error = EBUSY;
+ else
+ td->td_sigblock_val = 0;
+ } else
+ error = EDOOFUS;
+
+ /*
+ * Rely on normal ast mechanism to deliver pending
+ * signals to current thread. But notify others about
+ * fake unblock.
+ */
+ p = td->td_proc;
+ if (error == 0 && p->p_numthreads != 1) {
+ PROC_LOCK(p);
+ reschedule_signals(p, td->td_sigmask, 0);
+ PROC_UNLOCK(p);
+ }
+ break;
+
+ case FAST_SIGBLOCK_UNSETPTR:
+ if ((td->td_pflags & TDP_FAST_SIGBLOCK) != 0) {
+ error = copyin(td->td_sigblock_ptr, &oldval,
+ sizeof(uint32_t));
+ if (error != 0)
+ break;
+ if (oldval != 0 && oldval != FAST_SIGBLOCK_PEND)
+ error = EBUSY;
+ else {
+ td->td_pflags &= ~TDP_FAST_SIGBLOCK;
+ td->td_sigblock_val = 0;
+ }
+ } else
+ error = EDOOFUS;
+ break;
+ }
+ return (error);
+}
+
+void
+fetch_fast_sigblock(struct thread *td)
+{
+
+ if ((td->td_pflags & TDP_FAST_SIGBLOCK) == 0)
+ return;
+ td->td_sigblock_val = fuword32(td->td_sigblock_ptr);
+ if (td->td_sigblock_val == -1)
+ fetch_fast_sigblock_failed(td, 0);
+}
+
+void
+fetch_fast_sigblock_failed(struct thread *td, int write)
+{
+ ksiginfo_t ksi;
+
+ td->td_sigblock_val = 0;
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGSEGV;
+ ksi.ksi_code = write ? SEGV_ACCERR : SEGV_MAPERR;
+ ksi.ksi_addr = td->td_sigblock_ptr;
+ trapsignal(td, &ksi);
+}
Index: sys/kern/subr_syscall.c
===================================================================
--- sys/kern/subr_syscall.c
+++ sys/kern/subr_syscall.c
@@ -128,6 +128,12 @@
(*systrace_probe_func)(sa, SYSTRACE_ENTRY, 0);
#endif
+ /*
+ * Fetch fast sigblock value at the time of syscall
+ * entry because sleepqueue primitives might call
+ * cursig().
+ */
+ fetch_fast_sigblock(td);
AUDIT_SYSCALL_ENTER(sa->code, td);
error = (sa->callp->sy_call)(td, sa->args);
AUDIT_SYSCALL_EXIT(error, td);
Index: sys/kern/subr_trap.c
===================================================================
--- sys/kern/subr_trap.c
+++ sys/kern/subr_trap.c
@@ -207,8 +207,8 @@
{
struct thread *td;
struct proc *p;
- int flags;
- int sig;
+ uint32_t oldval;
+ int flags, sig;
td = curthread;
p = td->td_proc;
@@ -307,6 +307,7 @@
*/
if (flags & TDF_NEEDSIGCHK || p->p_pendingcnt > 0 ||
!SIGISEMPTY(p->p_siglist)) {
+ fetch_fast_sigblock(td);
PROC_LOCK(p);
mtx_lock(&p->p_sigacts->ps_mtx);
while ((sig = cursig(td)) != 0) {
@@ -316,6 +317,25 @@
mtx_unlock(&p->p_sigacts->ps_mtx);
PROC_UNLOCK(p);
}
+
+ /*
+ * Handle deferred update of the fast sigblock value, after
+ * the postsig() loop was performed.
+ */
+ if (td->td_pflags & TDP_FAST_SIGPENDING) {
+ td->td_pflags &= ~TDP_FAST_SIGPENDING;
+ oldval = fuword32(td->td_sigblock_ptr);
+ if (oldval == -1) {
+ fetch_fast_sigblock_failed(td, 0);
+ } else {
+ oldval |= FAST_SIGBLOCK_PEND;
+ if (suword32(td->td_sigblock_ptr, oldval) == -1)
+ fetch_fast_sigblock_failed(td, 1);
+ else
+ td->td_sigblock_val = oldval;
+ }
+ }
+
/*
* We need to check to see if we have to exit or wait due to a
* single threading requirement or some other STOP condition.
Index: sys/kern/syscalls.master
===================================================================
--- sys/kern/syscalls.master
+++ sys/kern/syscalls.master
@@ -1023,6 +1023,7 @@
struct kevent *changelist, int nchanges, \
struct kevent *eventlist, int nevents, \
const struct timespec *timeout); }
+561 AUE_NULL STD { int fast_sigblock(int cmd, uint32_t *ptr); }
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master
Index: sys/mips/include/elf.h
===================================================================
--- sys/mips/include/elf.h
+++ sys/mips/include/elf.h
@@ -147,8 +147,9 @@
#define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */
#define AT_HWCAP 25 /* CPU feature flags. */
#define AT_HWCAP2 26 /* CPU feature flags 2. */
+#define AT_BSDFLAGS 27 /* ELF BSD Flags. */
-#define AT_COUNT 27 /* Count of defined aux entry types. */
+#define AT_COUNT 28 /* Count of defined aux entry types. */
#define ET_DYN_LOAD_ADDR 0x0120000
Index: sys/powerpc/include/elf.h
===================================================================
--- sys/powerpc/include/elf.h
+++ sys/powerpc/include/elf.h
@@ -110,8 +110,9 @@
#define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */
#define AT_HWCAP 25 /* CPU feature flags. */
#define AT_HWCAP2 26 /* CPU feature flags 2. */
+#define AT_BSDFLAGS 27 /* ELF BSD Flags. */
-#define AT_COUNT 27 /* Count of defined aux entry types. */
+#define AT_COUNT 28 /* Count of defined aux entry types. */
/*
* Relocation types.
Index: sys/sparc64/include/elf.h
===================================================================
--- sys/sparc64/include/elf.h
+++ sys/sparc64/include/elf.h
@@ -95,8 +95,9 @@
#define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */
#define AT_HWCAP 25 /* CPU feature flags. */
#define AT_HWCAP2 26 /* CPU feature flags 2. */
+#define AT_BSDFLAGS 27 /* ELF BSD Flags. */
-#define AT_COUNT 27 /* Count of defined aux entry types. */
+#define AT_COUNT 28 /* Count of defined aux entry types. */
/* Define "machine" characteristics */
#if __ELF_WORD_SIZE == 32
Index: sys/sys/elf_common.h
===================================================================
--- sys/sys/elf_common.h
+++ sys/sys/elf_common.h
@@ -1342,5 +1342,6 @@
#define R_X86_64_TLSDESC 36
#define R_X86_64_IRELATIVE 37
+#define ELF_BSDF_FASTSIGBLK 0x0001 /* Kernel supports fast sigblock */
#endif /* !_SYS_ELF_COMMON_H_ */
Index: sys/sys/proc.h
===================================================================
--- sys/sys/proc.h
+++ sys/sys/proc.h
@@ -302,6 +302,8 @@
uintptr_t td_rb_inact; /* (k) Current in-action mutex loc. */
struct syscall_args td_sa; /* (kx) Syscall parameters. Copied on
fork for child tracing. */
+ void *td_sigblock_ptr; /* (k) uptr for fast sigblock. */
+ uint32_t td_sigblock_val; /* (k) fast sigblock value at
#define td_endcopy td_pcb
/*
@@ -442,7 +444,7 @@
#define TDP_ALTSTACK 0x00000020 /* Have alternate signal stack. */
#define TDP_DEADLKTREAT 0x00000040 /* Lock acquisition - deadlock treatment. */
#define TDP_NOFAULTING 0x00000080 /* Do not handle page faults. */
-#define TDP_UNUSED9 0x00000100 /* --available-- */
+#define TDP_FAST_SIGBLOCK 0x00000100 /* Fast sigblock active */
#define TDP_OWEUPC 0x00000200 /* Call addupc() at next AST. */
#define TDP_ITHREAD 0x00000400 /* Thread is an interrupt thread. */
#define TDP_SYNCIO 0x00000800 /* Local override, disable async i/o. */
@@ -465,6 +467,7 @@
#define TDP_UIOHELD 0x10000000 /* Current uio has pages held in td_ma */
#define TDP_FORKING 0x20000000 /* Thread is being created through fork() */
#define TDP_EXECVMSPC 0x40000000 /* Execve destroyed old vmspace */
+#define TDP_FAST_SIGPENDING 0x80000000
/*
* Reasons that the current thread can not be run yet.
Index: sys/sys/signalvar.h
===================================================================
--- sys/sys/signalvar.h
+++ sys/sys/signalvar.h
@@ -254,6 +254,20 @@
/* Flags for ksi_flags */
#define SQ_INIT 0x01
+/*
+ * Fast_sigblock
+ */
+#define FAST_SIGBLOCK_SETPTR 1
+#define FAST_SIGBLOCK_UNBLOCK 2
+#define FAST_SIGBLOCK_UNSETPTR 3
+
+#define FAST_SIGBLOCK_PEND 0x1
+#define FAST_SIGBLOCK_INC 0x10
+
+#ifndef _KERNEL
+int __sys_fast_sigblock(int cmd, void *ptr);
+#endif
+
#ifdef _KERNEL
/* Return nonzero if process p has an unmasked pending signal. */
@@ -363,6 +377,8 @@
int cursig(struct thread *td);
void execsigs(struct proc *p);
+void fetch_fast_sigblock(struct thread *td);
+void fetch_fast_sigblock_failed(struct thread *td, int write);
void gsignal(int pgid, int sig, ksiginfo_t *ksi);
void killproc(struct proc *p, char *why);
ksiginfo_t * ksiginfo_alloc(int wait);
Index: sys/sys/sysctl.h
===================================================================
--- sys/sys/sysctl.h
+++ sys/sys/sysctl.h
@@ -896,6 +896,7 @@
#define KERN_PROC_SIGTRAMP 41 /* signal trampoline location */
#define KERN_PROC_CWD 42 /* process current working directory */
#define KERN_PROC_NFDS 43 /* number of open file descriptors */
+#define KERN_PROC_FASTSIGBLK 44 /* address of fastsigblk magic word
/*
* KERN_IPC identifiers
Index: sys/x86/include/elf.h
===================================================================
--- sys/x86/include/elf.h
+++ sys/x86/include/elf.h
@@ -103,8 +103,9 @@
#define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */
#define AT_HWCAP 25 /* CPU feature flags. */
#define AT_HWCAP2 26 /* CPU feature flags 2. */
+#define AT_BSDFLAGS 27 /* ELF BSD Flags. */
-#define AT_COUNT 27 /* Count of defined aux entry types. */
+#define AT_COUNT 28 /* Count of defined aux entry types. */
/*
* Relocation types.
@@ -191,8 +192,9 @@
#define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */
#define AT_HWCAP 25 /* CPU feature flags. */
#define AT_HWCAP2 26 /* CPU feature flags 2. */
+#define AT_BSDFLAGS 27 /* ELF BSD Flags. */
-#define AT_COUNT 27 /* Count of defined aux entry types. */
+#define AT_COUNT 28 /* Count of defined aux entry types. */
/*
* Relocation types.
Index: usr.bin/procstat/procstat_sigs.c
===================================================================
--- usr.bin/procstat/procstat_sigs.c
+++ usr.bin/procstat/procstat_sigs.c
@@ -35,6 +35,7 @@
#include <err.h>
#include <errno.h>
#include <signal.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -135,13 +136,17 @@
procstat_threads_sigs(struct procstat *procstat, struct kinfo_proc *kipp)
{
struct kinfo_proc *kip;
+ uintmax_t fastsigblk_addr;
+ int error, name[4], j, has_fastsigblk_addr;
+ pid_t pid;
int j;
unsigned int count, i;
+ size_t len;
char *threadid;
if ((procstat_opts & PS_OPT_NOHEADER) == 0)
- xo_emit("{T:/%5s %6s %-16s %-7s %4s}\n", "PID", "TID", "COMM",
- "SIG", "FLAGS");
+ xo_emit("{T:/%5s %6s %-16s %-7s %4s %-18s}\n", "PID", "TID", "COMM",
+ "SIG", "FLAGS", "FSIGBLK");
kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD,
kipp->ki_pid, &count);
@@ -153,6 +158,19 @@
kinfo_proc_sort(kip, count);
for (i = 0; i < count; i++) {
kipp = &kip[i];
+ len = sizeof(fastsigblk_addr);
+ name[2] = KERN_PROC_FASTSIGBLK;
+ name[3] = kipp->ki_tid;
+ error = sysctl(name, 4, &fastsigblk_addr, &len, NULL, 0);
+ if (error < 0) {
+ if (errno != ESRCH && errno != ENOTTY) {
+ warn("sysctl: kern.proc.fastsigblk: %d",
+ kipp->ki_tid);
+ }
+ has_fastsigblk_addr = 0;
+ } else
+ has_fastsigblk_addr = 1;
+
asprintf(&threadid, "%d", kipp->ki_tid);
if (threadid == NULL)
xo_errc(1, ENOMEM, "Failed to allocate memory in "
@@ -160,6 +178,7 @@
xo_open_container(threadid);
xo_emit("{e:thread_id/%6d/%d}", kipp->ki_tid);
xo_open_container("signals");
+
for (j = 1; j <= _SIG_MAXSIG; j++) {
xo_emit("{dk:process_id/%5d/%d} ", kipp->ki_pid);
xo_emit("{d:thread_id/%6d/%d} ", kipp->ki_tid);
@@ -168,6 +187,10 @@
xo_emit(" ");
procstat_print_sig(&kipp->ki_siglist, j, 'P');
procstat_print_sig(&kipp->ki_sigmask, j, 'B');
+ xo_emit(" ");
+ /* XXXKIB */
+ xo_emit("{ek:%#jx/%#jx", has_fastsigblk_addr ?
+ (uintmax_t)fastsigblk_addr : -1);
procstat_close_signame(j);
xo_emit("\n");
}

File Metadata

Mime Type
text/plain
Expires
Tue, Nov 11, 1:59 PM (6 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25164753
Default Alt Text
D12773.id34280.diff (22 KB)

Event Timeline