RFC: "nice" is per process

Julian Elischer julian at elischer.org
Sun Jun 13 22:18:56 GMT 2004


When splitting appart the process structure for theads, I made a mistake
and made the "nice" value a property of the ksegrp. This is wrong
because Posix specifies that Nice always affects the entire process,
so this patch moves it back to the process. This does not mean that all
threads will have the same priority, only that the nice value used to
influence their priority will be the same throughout the process.


comments?

I've sent this to several people without comment so i'm widenning the 
request group.

julian

-------------- next part --------------
? notes
? out
? dev/my/if_my.c.new
? i386/conf/LINT
Index: fs/specfs/spec_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/fs/specfs/spec_vnops.c,v
retrieving revision 1.222
diff -u -r1.222 spec_vnops.c
--- fs/specfs/spec_vnops.c	6 May 2004 05:03:21 -0000	1.222
+++ fs/specfs/spec_vnops.c	12 Jun 2004 06:52:51 -0000
@@ -470,11 +470,11 @@
 	/*
 	 * Slow down disk requests for niced processes.
 	 */
-	if (doslowdown && td && td->td_ksegrp->kg_nice > 0) {
+	if (doslowdown && td && td->td_proc->p_nice > 0) {
 		mtx_lock(&strategy_mtx);
 		msleep(&strategy_mtx, &strategy_mtx,
 		    PPAUSE | PCATCH | PDROP, "ioslow",
-		    td->td_ksegrp->kg_nice);
+		    td->td_proc->p_nice);
 	}
 	/*
 	 * Collect statistics on synchronous and asynchronous read
Index: i386/ibcs2/ibcs2_misc.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/ibcs2/ibcs2_misc.c,v
retrieving revision 1.54
diff -u -r1.54 ibcs2_misc.c
--- i386/ibcs2/ibcs2_misc.c	17 Mar 2004 20:00:00 -0000	1.54
+++ i386/ibcs2/ibcs2_misc.c	12 Jun 2004 06:52:53 -0000
@@ -951,10 +951,10 @@
 
 	sa.which = PRIO_PROCESS;
 	sa.who = 0;
-	sa.prio = td->td_ksegrp->kg_nice + uap->incr;
+	sa.prio = td->td_proc->p_nice + uap->incr;
 	if ((error = setpriority(td, &sa)) != 0)
 		return EPERM;
-	td->td_retval[0] = td->td_ksegrp->kg_nice;
+	td->td_retval[0] = td->td_proc->p_nice;
 	return 0;
 }
 
Index: kern/init_main.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/init_main.c,v
retrieving revision 1.242
diff -u -r1.242 init_main.c
--- kern/init_main.c	29 Feb 2004 16:56:54 -0000	1.242
+++ kern/init_main.c	12 Jun 2004 06:52:56 -0000
@@ -382,8 +382,8 @@
 	p->p_flag = P_SYSTEM;
 	p->p_sflag = PS_INMEM;
 	p->p_state = PRS_NORMAL;
+	p->p_nice = NZERO;
 	td->td_state = TDS_RUNNING;
-	kg->kg_nice = NZERO;
 	kg->kg_pri_class = PRI_TIMESHARE;
 	kg->kg_user_pri = PUSER;
 	td->td_priority = PVM;
Index: kern/kern_clock.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_clock.c,v
retrieving revision 1.169
diff -u -r1.169 kern_clock.c
--- kern/kern_clock.c	2 Jun 2004 12:05:06 -0000	1.169
+++ kern/kern_clock.c	12 Jun 2004 06:52:58 -0000
@@ -392,7 +392,7 @@
 		if (p->p_flag & P_SA)
 			thread_statclock(1);
 		p->p_uticks++;
-		if (td->td_ksegrp->kg_nice > NZERO)
+		if (p->p_nice > NZERO)
 			cp_time[CP_NICE]++;
 		else
 			cp_time[CP_USER]++;
Index: kern/kern_proc.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_proc.c,v
retrieving revision 1.203
diff -u -r1.203 kern_proc.c
--- kern/kern_proc.c	22 May 2004 23:11:44 -0000	1.203
+++ kern/kern_proc.c	12 Jun 2004 06:53:01 -0000
@@ -737,6 +737,7 @@
 		kp->ki_sflag = p->p_sflag;
 		kp->ki_swtime = p->p_swtime;
 		kp->ki_pid = p->p_pid;
+		kp->ki_nice = p->p_nice;
 		kg = td->td_ksegrp;
 		ke = td->td_kse;
 		bintime2timeval(&p->p_runtime, &tv);
@@ -748,7 +749,6 @@
 		kp->ki_slptime = kg->kg_slptime;
 		kp->ki_pri.pri_user = kg->kg_user_pri;
 		kp->ki_pri.pri_class = kg->kg_pri_class;
-		kp->ki_nice = kg->kg_nice;
 
 		/* Things in the thread */
 		kp->ki_wchan = td->td_wchan;
Index: kern/kern_resource.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_resource.c,v
retrieving revision 1.137
diff -u -r1.137 kern_resource.c
--- kern/kern_resource.c	8 May 2004 08:56:05 -0000	1.137
+++ kern/kern_resource.c	12 Jun 2004 06:53:02 -0000
@@ -88,7 +88,6 @@
 	struct thread *td;
 	register struct getpriority_args *uap;
 {
-	struct ksegrp *kg;
 	struct proc *p;
 	int error, low;
 
@@ -98,16 +97,13 @@
 
 	case PRIO_PROCESS:
 		if (uap->who == 0)
-			low = td->td_ksegrp->kg_nice;
+			low = td->td_proc->p_nice;
 		else {
 			p = pfind(uap->who);
 			if (p == NULL)
 				break;
 			if (p_cansee(td, p) == 0) {
-				FOREACH_KSEGRP_IN_PROC(p, kg) {
-					if (kg->kg_nice < low)
-						low = kg->kg_nice;
-				}
+				low = p->p_nice;
 			}
 			PROC_UNLOCK(p);
 		}
@@ -131,10 +127,8 @@
 		LIST_FOREACH(p, &pg->pg_members, p_pglist) {
 			PROC_LOCK(p);
 			if (!p_cansee(td, p)) {
-				FOREACH_KSEGRP_IN_PROC(p, kg) {
-					if (kg->kg_nice < low)
-						low = kg->kg_nice;
-				}
+				if (p->p_nice < low)
+					low = p->p_nice;
 			}
 			PROC_UNLOCK(p);
 		}
@@ -150,10 +144,8 @@
 			PROC_LOCK(p);
 			if (!p_cansee(td, p) &&
 			    p->p_ucred->cr_uid == uap->who) {
-				FOREACH_KSEGRP_IN_PROC(p, kg) {
-					if (kg->kg_nice < low)
-						low = kg->kg_nice;
-				}
+				if (p->p_nice < low)
+					low = p->p_nice;
 			}
 			PROC_UNLOCK(p);
 		}
@@ -260,19 +252,13 @@
 }
 
 /* 
- * Set "nice" for a process.  Doesn't really understand threaded processes
- * well but does try.  Has the unfortunate side effect of making all the NICE
- * values for a process's ksegrps the same.  This suggests that
- * NICE values should be stored as a process nice and deltas for the ksegrps.
- * (but not yet).
+ * Set "nice" for a (whole) process.
  */
 static int
 donice(struct thread *td, struct proc *p, int n)
 {
-	struct ksegrp *kg;
-	int error, low;
+	int error;
 
-	low = PRIO_MAX + 1;
 	PROC_LOCK_ASSERT(p, MA_OWNED);
 	if ((error = p_cansched(td, p)))
 		return (error);
@@ -280,20 +266,10 @@
 		n = PRIO_MAX;
 	if (n < PRIO_MIN)
 		n = PRIO_MIN;
-	/* 
-	 * Only allow nicing if to more than the lowest nice.
-	 * E.g., for nices of 4,3,2 allow nice to 3 but not 1
-	 */
-	FOREACH_KSEGRP_IN_PROC(p, kg) {
-		if (kg->kg_nice < low)
-			low = kg->kg_nice;
-	}
- 	if (n < low && suser(td) != 0)
+ 	if (n <  p->p_nice && suser(td) != 0)
 		return (EACCES);
 	mtx_lock_spin(&sched_lock);
-	FOREACH_KSEGRP_IN_PROC(p, kg) {
-		sched_nice(kg, n);
-	}
+	sched_nice(p, n);
 	mtx_unlock_spin(&sched_lock);
 	return (0);
 }
Index: kern/sched_4bsd.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/sched_4bsd.c,v
retrieving revision 1.37
diff -u -r1.37 sched_4bsd.c
--- kern/sched_4bsd.c	5 Apr 2004 21:03:35 -0000	1.37
+++ kern/sched_4bsd.c	12 Jun 2004 06:53:04 -0000
@@ -439,7 +439,7 @@
 
 	if (kg->kg_pri_class == PRI_TIMESHARE) {
 		newpriority = PUSER + kg->kg_estcpu / INVERSE_ESTCPU_WEIGHT +
-		    NICE_WEIGHT * (kg->kg_nice - PRIO_MIN);
+		    NICE_WEIGHT * (kg->kg_proc->p_nice - PRIO_MIN);
 		newpriority = min(max(newpriority, PRI_MIN_TIMESHARE),
 		    PRI_MAX_TIMESHARE);
 		kg->kg_user_pri = newpriority;
@@ -583,13 +583,16 @@
 }
 
 void
-sched_nice(struct ksegrp *kg, int nice)
+sched_nice(struct proc *p, int nice)
 {
+	struct ksegrp *kg;
 
-	PROC_LOCK_ASSERT(kg->kg_proc, MA_OWNED);
+	PROC_LOCK_ASSERT(p, MA_OWNED);
 	mtx_assert(&sched_lock, MA_OWNED);
-	kg->kg_nice = nice;
-	resetpriority(kg);
+	p->p_nice = nice;
+	FOREACH_KSEGRP_IN_PROC(p, kg) {
+		resetpriority(kg);
+	}
 }
 
 void
Index: kern/sched_ule.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/sched_ule.c,v
retrieving revision 1.106
diff -u -r1.106 sched_ule.c
--- kern/sched_ule.c	2 Jun 2004 05:46:48 -0000	1.106
+++ kern/sched_ule.c	12 Jun 2004 06:53:07 -0000
@@ -366,9 +366,9 @@
 		CTR6(KTR_ULE,
 		    "Add kse %p to %p (slice: %d, pri: %d, nice: %d(%d))",
 		    ke, ke->ke_runq, ke->ke_slice, ke->ke_thread->td_priority,
-		    ke->ke_ksegrp->kg_nice, kseq->ksq_nicemin);
+		    ke->ke_proc->p_nice, kseq->ksq_nicemin);
 	if (ke->ke_ksegrp->kg_pri_class == PRI_TIMESHARE)
-		kseq_nice_add(kseq, ke->ke_ksegrp->kg_nice);
+		kseq_nice_add(kseq, ke->ke_proc->p_nice);
 }
 
 static void
@@ -388,7 +388,7 @@
 	kseq->ksq_load--;
 	ke->ke_runq = NULL;
 	if (ke->ke_ksegrp->kg_pri_class == PRI_TIMESHARE)
-		kseq_nice_rem(kseq, ke->ke_ksegrp->kg_nice);
+		kseq_nice_rem(kseq, ke->ke_proc->p_nice);
 }
 
 static void
@@ -929,7 +929,7 @@
 
 	pri = SCHED_PRI_INTERACT(sched_interact_score(kg));
 	pri += SCHED_PRI_BASE;
-	pri += kg->kg_nice;
+	pri += kg->kg_proc->p_nice;
 
 	if (pri > PRI_MAX_TIMESHARE)
 		pri = PRI_MAX_TIMESHARE;
@@ -980,13 +980,13 @@
 	if (!SCHED_INTERACTIVE(kg)) {
 		int nice;
 
-		nice = kg->kg_nice + (0 - kseq->ksq_nicemin);
+		nice = kg->kg_proc->p_nice + (0 - kseq->ksq_nicemin);
 		if (kseq->ksq_load_timeshare == 0 ||
-		    kg->kg_nice < kseq->ksq_nicemin)
+		    kg->kg_proc->p_nice < kseq->ksq_nicemin)
 			ke->ke_slice = SCHED_SLICE_MAX;
 		else if (nice <= SCHED_SLICE_NTHRESH)
 			ke->ke_slice = SCHED_SLICE_NICE(nice);
-		else if (kg->kg_nice == 0)
+		else if (kg->kg_proc->p_nice == 0)
 			ke->ke_slice = SCHED_SLICE_MIN;
 		else
 			ke->ke_slice = 0;
@@ -995,7 +995,7 @@
 
 	CTR6(KTR_ULE,
 	    "Sliced %p(%d) (nice: %d, nicemin: %d, load: %d, interactive: %d)",
-	    ke, ke->ke_slice, kg->kg_nice, kseq->ksq_nicemin,
+	    ke, ke->ke_slice, kg->kg_proc->p_nice, kseq->ksq_nicemin,
 	    kseq->ksq_load_timeshare, SCHED_INTERACTIVE(kg));
 
 	return;
@@ -1167,29 +1167,35 @@
 }
 
 void
-sched_nice(struct ksegrp *kg, int nice)
+sched_nice(struct proc *p, int nice)
 {
+	struct ksegrp *kg;
 	struct kse *ke;
 	struct thread *td;
 	struct kseq *kseq;
 
-	PROC_LOCK_ASSERT(kg->kg_proc, MA_OWNED);
+	PROC_LOCK_ASSERT(p, MA_OWNED);
 	mtx_assert(&sched_lock, MA_OWNED);
 	/*
 	 * We need to adjust the nice counts for running KSEs.
 	 */
-	if (kg->kg_pri_class == PRI_TIMESHARE)
-		FOREACH_KSE_IN_GROUP(kg, ke) {
-			if (ke->ke_runq == NULL)
-				continue;
-			kseq = KSEQ_CPU(ke->ke_cpu);
-			kseq_nice_rem(kseq, kg->kg_nice);
-			kseq_nice_add(kseq, nice);
-		}
-	kg->kg_nice = nice;
-	sched_priority(kg);
-	FOREACH_THREAD_IN_GROUP(kg, td)
-		td->td_flags |= TDF_NEEDRESCHED;
+	FOREACH_KSEGRP_IN_PROC(p, kg) {
+		if (kg->kg_pri_class == PRI_TIMESHARE) {
+			FOREACH_KSE_IN_GROUP(kg, ke) {
+				if (ke->ke_runq == NULL)
+					continue;
+				kseq = KSEQ_CPU(ke->ke_cpu);
+				kseq_nice_rem(kseq, p->p_nice);
+				kseq_nice_add(kseq, nice);
+			}
+		}
+	}
+	p->p_nice = nice;
+	FOREACH_KSEGRP_IN_PROC(p, kg) {
+		sched_priority(kg);
+		FOREACH_THREAD_IN_GROUP(kg, td)
+			td->td_flags |= TDF_NEEDRESCHED;
+	}
 }
 
 void
@@ -1246,6 +1252,7 @@
 
 	mtx_assert(&sched_lock, MA_OWNED);
 
+	p1->p_nice = p->p_nice;
 	sched_fork_ksegrp(FIRST_KSEGRP_IN_PROC(p), FIRST_KSEGRP_IN_PROC(p1));
 	sched_fork_kse(FIRST_KSE_IN_PROC(p), FIRST_KSE_IN_PROC(p1));
 	sched_fork_thread(FIRST_THREAD_IN_PROC(p), FIRST_THREAD_IN_PROC(p1));
@@ -1273,7 +1280,6 @@
 	child->kg_slptime = kg->kg_slptime;
 	child->kg_runtime = kg->kg_runtime;
 	child->kg_user_pri = kg->kg_user_pri;
-	child->kg_nice = kg->kg_nice;
 	sched_interact_fork(child);
 	kg->kg_runtime += tickincr << 10;
 	sched_interact_update(kg);
@@ -1327,11 +1333,11 @@
 #endif
 		if (oclass == PRI_TIMESHARE) {
 			kseq->ksq_load_timeshare--;
-			kseq_nice_rem(kseq, kg->kg_nice);
+			kseq_nice_rem(kseq, kg->kg_proc->p_nice);
 		}
 		if (nclass == PRI_TIMESHARE) {
 			kseq->ksq_load_timeshare++;
-			kseq_nice_add(kseq, kg->kg_nice);
+			kseq_nice_add(kseq, kg->kg_proc->p_nice);
 		}
 	}
 
Index: sys/proc.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/proc.h,v
retrieving revision 1.378
diff -u -r1.378 proc.h
--- sys/proc.h	3 Jun 2004 01:47:36 -0000	1.378
+++ sys/proc.h	12 Jun 2004 06:53:20 -0000
@@ -509,7 +509,6 @@
 #define	kg_startcopy	kg_endzero
 	u_char		kg_pri_class;	/* (j) Scheduling class. */
 	u_char		kg_user_pri;	/* (j) User pri from estcpu and nice. */
-	signed char	kg_nice;	/* (c + j) Process "nice" value. */
 #define	kg_endcopy kg_numthreads
 	int		kg_numthreads;	/* (j) Num threads in total. */
 	int		kg_kses;	/* (j) Num KSEs in group. */
@@ -597,6 +596,7 @@
 	struct sysentvec *p_sysent;	/* (b) Syscall dispatch info. */
 	struct pargs	*p_args;	/* (c) Process arguments. */
 	rlim_t		p_cpulimit;	/* (j) Current CPU limit in seconds. */
+	signed char	p_nice;		/* (c + j) Process "nice" value. */
 /* End area that is copied on creation. */
 #define	p_endcopy	p_xstat
 
Index: sys/sched.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/sched.h,v
retrieving revision 1.11
diff -u -r1.11 sched.h
--- sys/sched.h	27 Feb 2004 18:52:44 -0000	1.11
+++ sys/sched.h	12 Jun 2004 06:53:20 -0000
@@ -55,7 +55,7 @@
 void	sched_class(struct ksegrp *kg, int class);
 void	sched_exit_ksegrp(struct ksegrp *kg, struct ksegrp *child);
 void	sched_fork_ksegrp(struct ksegrp *kg, struct ksegrp *child);
-void	sched_nice(struct ksegrp *kg, int nice);
+void	sched_nice(struct proc *p, int nice);
 
 /*
  * Threads are switched in and out, block on resources, have temporary
Index: ufs/ffs/ffs_snapshot.c
===================================================================
RCS file: /home/ncvs/src/sys/ufs/ffs/ffs_snapshot.c,v
retrieving revision 1.79
diff -u -r1.79 ffs_snapshot.c
--- ufs/ffs/ffs_snapshot.c	13 Feb 2004 02:02:06 -0000	1.79
+++ ufs/ffs/ffs_snapshot.c	12 Jun 2004 06:53:24 -0000
@@ -301,11 +301,11 @@
 	 *
 	 * Recind nice scheduling while running with the filesystem suspended.
 	 */
-	if (td->td_ksegrp->kg_nice > 0) {
+	if (td->td_proc->p_nice > 0) {
 		PROC_LOCK(td->td_proc);
 		mtx_lock_spin(&sched_lock);
-		saved_nice = td->td_ksegrp->kg_nice;
-		sched_nice(td->td_ksegrp, 0);
+		saved_nice = td->td_proc->p_nice;
+		sched_nice(td->td_proc, 0);
 		mtx_unlock_spin(&sched_lock);
 		PROC_UNLOCK(td->td_proc);
 	}
@@ -665,7 +665,7 @@
 	if (saved_nice > 0) {
 		PROC_LOCK(td->td_proc);
 		mtx_lock_spin(&sched_lock);
-		sched_nice(td->td_ksegrp, saved_nice);
+		sched_nice(td->td_proc, saved_nice);
 		mtx_unlock_spin(&sched_lock);
 		PROC_UNLOCK(td->td_proc);
 	}
Index: vm/vm_glue.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_glue.c,v
retrieving revision 1.197
diff -u -r1.197 vm_glue.c
--- vm/vm_glue.c	7 May 2004 11:43:24 -0000	1.197
+++ vm/vm_glue.c	12 Jun 2004 06:53:27 -0000
@@ -824,7 +824,7 @@
 				kg = td->td_ksegrp;
 				pri = p->p_swtime + kg->kg_slptime;
 				if ((p->p_sflag & PS_SWAPINREQ) == 0) {
-					pri -= kg->kg_nice * 8;
+					pri -= p->p_nice * 8;
 				}
 
 				/*
Index: vm/vm_pageout.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_pageout.c,v
retrieving revision 1.255
diff -u -r1.255 vm_pageout.c
--- vm/vm_pageout.c	12 May 2004 04:10:35 -0000	1.255
+++ vm/vm_pageout.c	12 Jun 2004 06:53:30 -0000
@@ -1225,12 +1225,9 @@
 		}
 		sx_sunlock(&allproc_lock);
 		if (bigproc != NULL) {
-			struct ksegrp *kg;
 			killproc(bigproc, "out of swap space");
 			mtx_lock_spin(&sched_lock);
-			FOREACH_KSEGRP_IN_PROC(bigproc, kg) {
-				sched_nice(kg, PRIO_MIN); /* XXXKSE ??? */
-			}
+			sched_nice(bigproc, PRIO_MIN);
 			mtx_unlock_spin(&sched_lock);
 			PROC_UNLOCK(bigproc);
 			wakeup(&cnt.v_free_count);


More information about the freebsd-current mailing list