diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index cdf757d..96e0b7c 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -2691,6 +2691,7 @@ killproc(p, why) p, p->p_pid, p->p_comm); log(LOG_ERR, "pid %d (%s), uid %d, was killed: %s\n", p->p_pid, p->p_comm, p->p_ucred ? p->p_ucred->cr_uid : -1, why); + p->p_flag |= P_WKILLED; psignal(p, SIGKILL); } diff --git a/sys/sys/proc.h b/sys/sys/proc.h index b65db62..405f2b5 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -573,7 +573,7 @@ struct proc { #define P_WAITED 0x01000 /* Someone is waiting for us. */ #define P_WEXIT 0x02000 /* Working on exiting. */ #define P_EXEC 0x04000 /* Process called exec. */ -#define P_UNUSED8000 0x08000 /* available. */ +#define P_WKILLED 0x08000 /* Killed, go to kernel/user boundary ASAP. */ #define P_CONTINUED 0x10000 /* Proc has continued from a stopped state. */ #define P_STOPPED_SIG 0x20000 /* Stopped due to SIGSTOP/SIGTSTP. */ #define P_STOPPED_TRACE 0x40000 /* Stopped because of tracing. */ @@ -592,6 +592,7 @@ struct proc { #define P_STOPPED (P_STOPPED_SIG|P_STOPPED_SINGLE|P_STOPPED_TRACE) #define P_SHOULDSTOP(p) ((p)->p_flag & P_STOPPED) +#define P_KILLED(p) ((p)->p_flag & P_WKILLED) /* * These were process status values (p_stat), now they are only used in diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 98b6b09..ade3355 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -217,7 +217,7 @@ vm_fault(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type, vm_object_t next_object; vm_page_t marray[VM_FAULT_READ]; int hardfault; - int faultcount, ahead, behind; + int faultcount, ahead, behind, alloc_req; struct faultstate fs; struct vnode *vp; int locked, error; @@ -424,10 +424,23 @@ RetryFault:; fs.pindex; } #endif + /* + * Unlocked read of the p_flag is + * harmless. At worst, the P_KILLED + * might be not observed there, and + * allocation can fail, causing + * restart and new reading of the + * p_flag. + */ + if (P_KILLED(curproc)) + alloc_req = VM_ALLOC_SYSTEM; + else if (fs.object->type == OBJT_VNODE || + fs.object->backing_object != NULL) + alloc_req = VM_ALLOC_NORMAL; + else + alloc_req = VM_ALLOC_ZERO; fs.m = vm_page_alloc(fs.object, fs.pindex, - (fs.object->type == OBJT_VNODE || - fs.object->backing_object != NULL) ? - VM_ALLOC_NORMAL : VM_ALLOC_ZERO); + alloc_req); } if (fs.m == NULL) { unlock_and_deallocate(&fs); @@ -435,6 +448,11 @@ RetryFault:; goto RetryFault; } else if (fs.m->valid == VM_PAGE_BITS_ALL) break; + else if (alloc_req == VM_ALLOC_SYSTEM && + fs.object->type != OBJT_VNODE && + fs.object->backing_object == NULL && + (fs.m->flags & PG_ZERO) == 0) + pmap_zero_page(fs.m); } readrest: @@ -452,7 +470,8 @@ readrest: int reqpage = 0; u_char behavior = vm_map_entry_behavior(fs.entry); - if (behavior == MAP_ENTRY_BEHAV_RANDOM) { + if (behavior == MAP_ENTRY_BEHAV_RANDOM || + P_KILLED(curproc)) { ahead = 0; behind = 0; } else { diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index 19edce1..e429925 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -1204,10 +1204,10 @@ vm_pageout_oom(int shortage) if (PROC_TRYLOCK(p) == 0) continue; /* - * If this is a system or protected process, skip it. + * If this is a system, protected or killed process, skip it. */ if ((p->p_flag & (P_INEXEC | P_PROTECTED | P_SYSTEM)) || - (p->p_pid == 1) || + (p->p_pid == 1) || P_KILLED(p) || ((p->p_pid < 48) && (swap_pager_avail != 0))) { PROC_UNLOCK(p); continue;