Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F135529018
D12773.id34280.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
22 KB
Referenced Files
None
Subscribers
None
D12773.id34280.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D12773: Manage thread signal mask using a shared word, instead of syscall.
Attached
Detach File
Event Timeline
Log In to Comment