diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index ede414f..b26eb63 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.231 2006/11/03 15:23:14 rrs Exp + * created from FreeBSD */ #include "opt_compat.h" @@ -504,4 +504,6 @@ struct sysent sysent[] = { { AS(sctp_generic_sendmsg_args), (sy_call_t *)sctp_generic_sendmsg, AUE_NULL, NULL, 0, 0 }, /* 472 = sctp_generic_sendmsg */ { AS(sctp_generic_sendmsg_iov_args), (sy_call_t *)sctp_generic_sendmsg_iov, AUE_NULL, NULL, 0, 0 }, /* 473 = sctp_generic_sendmsg_iov */ { AS(sctp_generic_recvmsg_args), (sy_call_t *)sctp_generic_recvmsg, AUE_NULL, NULL, 0, 0 }, /* 474 = sctp_generic_recvmsg */ + { AS(sched_setaffinity_args), (sy_call_t *)sched_setaffinity, AUE_NULL, NULL, 0, 0 }, /* 475 = sched_setaffinity */ + { AS(sched_getaffinity_args), (sy_call_t *)sched_getaffinity, AUE_NULL, NULL, 0, 0 }, /* 476 = sched_getaffinity */ }; diff --git a/sys/kern/kern_switch.c b/sys/kern/kern_switch.c index 1cbb659..ff95166 100644 --- a/sys/kern/kern_switch.c +++ b/sys/kern/kern_switch.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #else /* KERN_SWITCH_INCLUDE */ #if defined(SMP) && (defined(__i386__) || defined(__amd64__)) #include @@ -393,11 +394,13 @@ again: } bit = 0; } +#if 0 if (start != 0) { CTR0(KTR_RUNQ, "runq_findbit_from: restarting"); start = 0; goto again; } +#endif return (-1); } @@ -495,10 +498,14 @@ runq_choose(struct runq *rq) { struct rqhead *rqh; struct td_sched *ts; + struct td_sched *ts2; int pri; while ((pri = runq_findbit(rq)) != -1) { +again: rqh = &rq->rq_queues[pri]; +/* XXX */ +#if 0 #if defined(SMP) && defined(SCHED_4BSD) /* fuzz == 1 is normal.. 0 or less are ignored */ if (runq_fuzz > 1) { @@ -520,7 +527,33 @@ runq_choose(struct runq *rq) } } else #endif - ts = TAILQ_FIRST(rqh); +#endif + ts = NULL; + ts2 = TAILQ_FIRST(rqh); + while (ts2) { + cpumask_t me = PCPU_GET(cpumask); + if (ts2->ts_thread->td_cpumask == 0) { + if (bootverbose) + printf("%s: thread %p (%s) with 0 cpumask\n", + __func__, ts2->ts_thread, ts2->ts_thread->td_proc->p_comm); + ts = ts2; + break; + } + if ((ts2->ts_thread->td_cpumask & me) != 0) { + ts = ts2; + break; + } + //printf("%s: no match mask %x me %x\n", __func__, ts2->ts_thread->td_cpumask, me); + ts2 = TAILQ_NEXT(ts2, ts_procq); + } + if (ts == NULL) { + //printf("%s: ts not found pri %d\n", __func__, pri); + pri = runq_findbit_from(rq, pri + 1); + if (pri == -1) + break; + //printf("%s: going to next pri %d\n", __func__, pri); + goto again; + } KASSERT(ts != NULL, ("runq_choose: no proc on busy queue")); CTR3(KTR_RUNQ, "runq_choose: pri=%d td_sched=%p rqh=%p", pri, ts, rqh); @@ -630,4 +663,32 @@ sched_newthread(struct thread *td) ts->ts_thread = td; } +int +sched_setaffinity(struct thread *td, struct sched_setaffinity_args *uap) +{ + cpumask_t me; + + if (uap->mask == 0) + return (EINVAL); + me = PCPU_GET(cpumask); + printf("%s: setting mask %x old %x currcpu %x\n", __func__, uap->mask, td->td_cpumask, me); + td->td_cpumask = uap->mask; + if ((uap->mask & me) == 0) { + thread_lock(curthread); + mi_switch(SW_VOL, NULL); + thread_unlock(curthread); + } + return (0); +} + +int +sched_getaffinity(struct thread *td, struct sched_getaffinity_args *uap) +{ + int error; + + printf("%s: mask %x\n", __func__, td->td_cpumask); + error = copyout(&td->td_cpumask, uap->mask, sizeof(cpumask_t)); + return (error); +} + #endif /* KERN_SWITCH_INCLUDE */ diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c index 91870d4..57ae068 100644 --- a/sys/kern/kern_thread.c +++ b/sys/kern/kern_thread.c @@ -119,6 +119,7 @@ thread_ctor(void *mem, int size, void *arg, int flags) td->td_tid = alloc_unr(tid_unrhdr); td->td_syscalls = 0; + td->td_cpumask = ~0; /* * Note that td_critnest begins life as 1 because the thread is not diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c index 7e368bb..7e519fa 100644 --- a/sys/kern/sched_4bsd.c +++ b/sys/kern/sched_4bsd.c @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -119,7 +120,7 @@ static void updatepri(struct thread *td); static void resetpriority(struct thread *td); static void resetpriority_thread(struct thread *td); #ifdef SMP -static int forward_wakeup(int cpunum); +static int forward_wakeup(struct td_sched *ts, int cpunum); #endif static struct kproc_desc sched_kp = { @@ -949,7 +950,7 @@ sched_wakeup(struct thread *td) #ifdef SMP /* enable HTT_2 if you have a 2-way HTT cpu.*/ static int -forward_wakeup(int cpunum) +forward_wakeup(struct td_sched *ts, int cpunum) { cpumask_t map, me, dontuse; cpumask_t map2; @@ -979,7 +980,8 @@ forward_wakeup(int cpunum) if ((me & idle_cpus_mask) && (cpunum == NOCPU || me == (1 << cpunum))) return (0); - dontuse = me | stopped_cpus | hlt_cpus_mask; + dontuse = me | stopped_cpus | hlt_cpus_mask | + ~ts->ts_thread->td_cpumask; map3 = 0; if (forward_wakeup_use_loop) { SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { @@ -1128,8 +1130,9 @@ sched_add(struct thread *td, int flags) int idle = idle_cpus_mask & me; if (!idle && ((flags & SRQ_INTR) == 0) && - (idle_cpus_mask & ~(hlt_cpus_mask | me))) - forwarded = forward_wakeup(cpu); + (idle_cpus_mask & ~(hlt_cpus_mask | me | + ~td->td_cpumask))) + forwarded = forward_wakeup(ts, cpu); } if (!forwarded) { diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index c450690..97b7a1f 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.231 2006/11/03 15:23:14 rrs Exp + * created from FreeBSD */ const char *syscallnames[] = { @@ -482,4 +482,6 @@ const char *syscallnames[] = { "sctp_generic_sendmsg", /* 472 = sctp_generic_sendmsg */ "sctp_generic_sendmsg_iov", /* 473 = sctp_generic_sendmsg_iov */ "sctp_generic_recvmsg", /* 474 = sctp_generic_recvmsg */ + "sched_setaffinity", /* 475 = sched_setaffinity */ + "sched_getaffinity", /* 476 = sched_getaffinity */ }; diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index dd9e25f..811ee4d 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -835,5 +835,7 @@ 474 AUE_NULL STD { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, \ struct sockaddr * from, __socklen_t *fromlenaddr, \ struct sctp_sndrcvinfo *sinfo, int *msg_flags); } +475 AUE_NULL STD { int sched_setaffinity(cpumask_t mask); } +476 AUE_NULL STD { int sched_getaffinity(cpumask_t *mask); } ; Please copy any additions and changes to the following compatability tables: ; sys/compat/freebsd32/syscalls.master diff --git a/sys/kern/systrace_args.c b/sys/kern/systrace_args.c index 6aef4a0..769b925 100644 --- a/sys/kern/systrace_args.c +++ b/sys/kern/systrace_args.c @@ -2805,6 +2805,20 @@ systrace_args(int sysnum, void *params, u_int64_t *uarg, int *n_args) *n_args = 7; break; } + /* sched_setaffinity */ + case 475: { + struct sched_setaffinity_args *p = params; + iarg[0] = p->mask; /* cpumask_t */ + *n_args = 1; + break; + } + /* sched_getaffinity */ + case 476: { + struct sched_getaffinity_args *p = params; + uarg[0] = (intptr_t) p->mask; /* cpumask_t * */ + *n_args = 1; + break; + } default: *n_args = 0; break; diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 7282a38..a41b9db 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -300,6 +300,7 @@ struct thread { struct td_sched *td_sched; /* (*) Scheduler-specific data. */ struct kaudit_record *td_ar; /* (k) Active audit record, if any. */ int td_syscalls; /* per-thread syscall count (used by NFS :)) */ + cpumask_t td_cpumask; /* (j) CPUs we're allowed on */ }; struct mtx *thread_lock_block(struct thread *); diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index aafc65c..df5774f 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.231 2006/11/03 15:23:14 rrs Exp + * created from FreeBSD */ #define SYS_syscall 0 @@ -394,4 +394,6 @@ #define SYS_sctp_generic_sendmsg 472 #define SYS_sctp_generic_sendmsg_iov 473 #define SYS_sctp_generic_recvmsg 474 -#define SYS_MAXSYSCALL 475 +#define SYS_sched_setaffinity 475 +#define SYS_sched_getaffinity 476 +#define SYS_MAXSYSCALL 477 diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index a36dd58..ba3160c 100644 --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -1,7 +1,7 @@ # FreeBSD system call names. # DO NOT EDIT-- this file is automatically generated. # $FreeBSD$ -# created from FreeBSD: src/sys/kern/syscalls.master,v 1.231 2006/11/03 15:23:14 rrs Exp +# created from FreeBSD MIASM = \ syscall.o \ exit.o \ @@ -335,4 +335,6 @@ MIASM = \ sctp_peeloff.o \ sctp_generic_sendmsg.o \ sctp_generic_sendmsg_iov.o \ - sctp_generic_recvmsg.o + sctp_generic_recvmsg.o \ + sched_setaffinity.o \ + sched_getaffinity.o diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index 6eea1e0..5a6c6f7 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.231 2006/11/03 15:23:14 rrs Exp + * created from FreeBSD */ #ifndef _SYS_SYSPROTO_H_ @@ -1482,6 +1482,12 @@ struct sctp_generic_recvmsg_args { char sinfo_l_[PADL_(struct sctp_sndrcvinfo *)]; struct sctp_sndrcvinfo * sinfo; char sinfo_r_[PADR_(struct sctp_sndrcvinfo *)]; char msg_flags_l_[PADL_(int *)]; int * msg_flags; char msg_flags_r_[PADR_(int *)]; }; +struct sched_setaffinity_args { + char mask_l_[PADL_(cpumask_t)]; cpumask_t mask; char mask_r_[PADR_(cpumask_t)]; +}; +struct sched_getaffinity_args { + char mask_l_[PADL_(cpumask_t *)]; cpumask_t * mask; char mask_r_[PADR_(cpumask_t *)]; +}; int nosys(struct thread *, struct nosys_args *); void sys_exit(struct thread *, struct sys_exit_args *); int fork(struct thread *, struct fork_args *); @@ -1814,6 +1820,8 @@ int sctp_peeloff(struct thread *, struct sctp_peeloff_args *); int sctp_generic_sendmsg(struct thread *, struct sctp_generic_sendmsg_args *); int sctp_generic_sendmsg_iov(struct thread *, struct sctp_generic_sendmsg_iov_args *); int sctp_generic_recvmsg(struct thread *, struct sctp_generic_recvmsg_args *); +int sched_setaffinity(struct thread *, struct sched_setaffinity_args *); +int sched_getaffinity(struct thread *, struct sched_getaffinity_args *); #ifdef COMPAT_43 @@ -2365,6 +2373,8 @@ int freebsd4_sigreturn(struct thread *, struct freebsd4_sigreturn_args *); #define SYS_AUE_sctp_generic_sendmsg AUE_NULL #define SYS_AUE_sctp_generic_sendmsg_iov AUE_NULL #define SYS_AUE_sctp_generic_recvmsg AUE_NULL +#define SYS_AUE_sched_setaffinity AUE_NULL +#define SYS_AUE_sched_getaffinity AUE_NULL #undef PAD_ #undef PADL_