From cb7f4ab1af324a9bc5946f35225f67364f4b812b Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Wed, 16 Nov 2005 02:24:33 +0000 Subject: [PATCH] Continue work on our pluggable scheduler abstraction. Implement a system call to set the scheduler for the current process (and future children), and add an abstraction for scheduler registration. Submitted-by: Sergey Glushchenko --- sys/conf/files | 3 +- sys/i386/i386/machdep.c | 5 +- sys/kern/init_sysent.c | 5 +- sys/kern/kern_usched.c | 169 +++++++++++++++++++++++++++++++ sys/kern/syscalls.c | 5 +- sys/kern/syscalls.master | 3 +- sys/kern/usched_bsd4.c | 7 +- sys/platform/pc32/i386/machdep.c | 5 +- sys/sys/syscall-args | 5 +- sys/sys/syscall-hide.h | 5 +- sys/sys/syscall.h | 7 +- sys/sys/syscall.mk | 7 +- sys/sys/sysproto.h | 13 ++- sys/sys/sysunion.h | 5 +- sys/sys/usched.h | 29 +++++- 15 files changed, 246 insertions(+), 27 deletions(-) create mode 100644 sys/kern/kern_usched.c diff --git a/sys/conf/files b/sys/conf/files index 3bac80164e..6b9b5c6b1d 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,5 +1,5 @@ # $FreeBSD: src/sys/conf/files,v 1.340.2.137 2003/06/04 17:10:30 sam Exp $ -# $DragonFly: src/sys/conf/files,v 1.110 2005/11/02 18:41:50 dillon Exp $ +# $DragonFly: src/sys/conf/files,v 1.111 2005/11/16 02:24:26 dillon Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -519,6 +519,7 @@ kern/kern_upcall.c standard kern/kern_sfbuf.c standard kern/kern_msfbuf.c standard kern/kern_subr.c standard +kern/kern_usched.c standard kern/usched_bsd4.c standard kern/kern_umtx.c standard kern/lwkt_thread.c standard diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 5965294284..e925248e52 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -36,7 +36,7 @@ * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 * $FreeBSD: src/sys/i386/i386/machdep.c,v 1.385.2.30 2003/05/31 08:48:05 alc Exp $ - * $DragonFly: src/sys/i386/i386/Attic/machdep.c,v 1.82 2005/11/04 08:57:27 dillon Exp $ + * $DragonFly: src/sys/i386/i386/Attic/machdep.c,v 1.83 2005/11/16 02:24:28 dillon Exp $ */ #include "use_apm.h" @@ -73,6 +73,7 @@ #include #include #include +#include #include #include @@ -1868,7 +1869,7 @@ init386(int first) LIST_INSERT_HEAD(&proc0.p_lwps, &proc0.p_lwp, lwp_list); proc0.p_lwp.lwp_thread = &thread0; proc0.p_lwp.lwp_proc = &proc0; - proc0.p_usched = &usched_bsd4; + proc0.p_usched = usched_init(); varsymset_init(&proc0.p_varsymset, NULL); thread0.td_flags |= TDF_RUNNING; thread0.td_proc = &proc0; diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 17c8fcdd1d..7676228b76 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -2,8 +2,8 @@ * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/kern/init_sysent.c,v 1.33 2005/08/27 20:23:05 joerg Exp $ - * created from DragonFly: src/sys/kern/syscalls.master,v 1.26 2005/08/02 13:03:55 joerg Exp + * $DragonFly: src/sys/kern/init_sysent.c,v 1.34 2005/11/16 02:24:30 dillon Exp $ + * created from DragonFly: src/sys/kern/syscalls.master,v 1.27 2005/08/27 20:23:05 joerg Exp */ #include "opt_compat.h" @@ -515,4 +515,5 @@ struct sysent sysent[] = { { AS(fhstat_args), (sy_call_t *)fhstat }, /* 478 = fhstat */ { AS(getdirentries_args), (sy_call_t *)getdirentries }, /* 479 = getdirentries */ { AS(getdents_args), (sy_call_t *)getdents }, /* 480 = getdents */ + { AS(usched_set_args), (sy_call_t *)usched_set }, /* 481 = usched_set */ }; diff --git a/sys/kern/kern_usched.c b/sys/kern/kern_usched.c new file mode 100644 index 0000000000..f7a1502efc --- /dev/null +++ b/sys/kern/kern_usched.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2005 The DragonFly Project. All rights reserved. + * + * This code is derived from software contributed to The DragonFly Project + * by Sergey Glushchenko + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of The DragonFly Project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific, prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $DragonFly: src/sys/kern/kern_usched.c,v 1.1 2005/11/16 02:24:30 dillon Exp $ + */ + +#include +#include /* curthread */ +#include +#include /* struct usched_set_args */ +#include /* strcmp() */ +#include + +static TAILQ_HEAD(, usched) usched_list = TAILQ_HEAD_INITIALIZER(usched_list); + +/* + * Called from very low level boot code, i386/i386/machdep.c/init386(). + * We cannot do anything fancy. no malloc's, no nothing other then + * static initialization. + */ +struct usched * +usched_init(void) +{ + /* + * Add the bsd4 userland scheduler to the system. + */ + usched_ctl(&usched_bsd4, USCH_ADD); + return(&usched_bsd4); +} + +/* + * USCHED_CTL + * + * SYNOPSIS: + * Add/remove usched to/from list. + * + * ARGUMENTS: + * usched - pointer to target scheduler + * action - addition or removal ? + * + * RETURN VALUES: + * 0 - success + * EINVAL - error + */ +int +usched_ctl(struct usched *usched, int action) +{ + struct usched *item; /* temporaly for TAILQ processing */ + int error = 0; + + switch(action) { + case USCH_ADD: + /* + * Make sure it isn't already on the list + */ +#ifdef INVARIANTS + TAILQ_FOREACH(item, &usched_list, entry) { + KKASSERT(item != usched); + } +#endif + /* + * Optional callback to the scheduler before we officially + * add it to the list. + */ + if (usched->usched_register) + usched->usched_register(); + TAILQ_INSERT_TAIL(&usched_list, usched, entry); + break; + case USCH_REM: + /* + * Do not allow the default scheduler to be removed + */ + if (strcmp(usched->name, "bsd4") == 0) { + error = EINVAL; + break; + } + TAILQ_FOREACH(item, &usched_list, entry) { + if (item == usched) + break; + } + if (item) { + if (item->usched_unregister) + item->usched_unregister(); + TAILQ_REMOVE(&usched_list, item, entry); + } else { + error = EINVAL; + } + break; + default: + error = EINVAL; + break; + } + return (error); +} + +/* + * USCHED_SET(syscall) + * + * SYNOPSIS: + * Setting up a proc's usched. + * + * ARGUMENTS: + * name - usched's name + * + * RETURN VALUES: + * 0 - success + * EINVAL - error + */ +int +usched_set(struct usched_set_args *uap) +{ + struct proc *p = curthread->td_proc; + struct usched *item; /* temporaly for TAILQ processing */ + int error; + + if ((error = suser(curthread)) != 0) + return (error); + + TAILQ_FOREACH(item, &usched_list, entry) { + if (strcmp(item->name, uap->name) == 0) + break; + } + + /* + * If the scheduler for a process is being changed, disassociate + * the old scheduler before switching to the new one. + * + * XXX we might have to add an additional ABI call to do a 'full + * disassociation' and another ABI call to do a 'full reassociation' + */ + if (item && item != p->p_usched) { + p->p_usched->release_curproc(&p->p_lwp); + p->p_usched = item; + } else if (item == NULL) { + error = EINVAL; + } + return (error); +} + diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index d61831cc28..76f87803db 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -2,8 +2,8 @@ * System call names. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/kern/syscalls.c,v 1.32 2005/08/27 20:23:05 joerg Exp $ - * created from DragonFly: src/sys/kern/syscalls.master,v 1.26 2005/08/02 13:03:55 joerg Exp + * $DragonFly: src/sys/kern/syscalls.c,v 1.33 2005/11/16 02:24:30 dillon Exp $ + * created from DragonFly: src/sys/kern/syscalls.master,v 1.27 2005/08/27 20:23:05 joerg Exp */ char *syscallnames[] = { @@ -490,4 +490,5 @@ char *syscallnames[] = { "fhstat", /* 478 = fhstat */ "getdirentries", /* 479 = getdirentries */ "getdents", /* 480 = getdents */ + "usched_set", /* 481 = usched_set */ }; diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 63dd69b7e2..c7d6abb03b 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ - $DragonFly: src/sys/kern/syscalls.master,v 1.27 2005/08/27 20:23:05 joerg Exp $ + $DragonFly: src/sys/kern/syscalls.master,v 1.28 2005/11/16 02:24:30 dillon Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 ; $FreeBSD: src/sys/kern/syscalls.master,v 1.72.2.10 2002/07/12 08:22:46 alfred Exp $ @@ -651,3 +651,4 @@ 479 STD BSD { int getdirentries(int fd, char *buf, u_int count, \ long *basep); } 480 STD BSD { int getdents(int fd, char *buf, size_t count); } +481 STD BSD { int usched_set(const char *name, int flags); } diff --git a/sys/kern/usched_bsd4.c b/sys/kern/usched_bsd4.c index 83fb7d9c24..ea004eef20 100644 --- a/sys/kern/usched_bsd4.c +++ b/sys/kern/usched_bsd4.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/usched_bsd4.c,v 1.4 2005/11/14 18:50:05 dillon Exp $ + * $DragonFly: src/sys/kern/usched_bsd4.c,v 1.5 2005/11/16 02:24:30 dillon Exp $ */ #include @@ -98,6 +98,8 @@ static void bsd4_recalculate_estcpu(struct lwp *lp); struct usched usched_bsd4 = { { NULL }, "bsd4", "Original DragonFly Scheduler", + NULL, /* default registration */ + NULL, /* default deregistration */ bsd4_acquire_curproc, bsd4_release_curproc, bsd4_select_curproc, @@ -107,7 +109,8 @@ struct usched usched_bsd4 = { bsd4_recalculate_estcpu, bsd4_resetpriority, bsd4_forking, - bsd4_exiting + bsd4_exiting, + NULL /* setcpumask not supported */ }; /* diff --git a/sys/platform/pc32/i386/machdep.c b/sys/platform/pc32/i386/machdep.c index 29c3d10dde..c5ad0b7783 100644 --- a/sys/platform/pc32/i386/machdep.c +++ b/sys/platform/pc32/i386/machdep.c @@ -36,7 +36,7 @@ * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 * $FreeBSD: src/sys/i386/i386/machdep.c,v 1.385.2.30 2003/05/31 08:48:05 alc Exp $ - * $DragonFly: src/sys/platform/pc32/i386/machdep.c,v 1.82 2005/11/04 08:57:27 dillon Exp $ + * $DragonFly: src/sys/platform/pc32/i386/machdep.c,v 1.83 2005/11/16 02:24:28 dillon Exp $ */ #include "use_apm.h" @@ -73,6 +73,7 @@ #include #include #include +#include #include #include @@ -1868,7 +1869,7 @@ init386(int first) LIST_INSERT_HEAD(&proc0.p_lwps, &proc0.p_lwp, lwp_list); proc0.p_lwp.lwp_thread = &thread0; proc0.p_lwp.lwp_proc = &proc0; - proc0.p_usched = &usched_bsd4; + proc0.p_usched = usched_init(); varsymset_init(&proc0.p_varsymset, NULL); thread0.td_flags |= TDF_RUNNING; thread0.td_proc = &proc0; diff --git a/sys/sys/syscall-args b/sys/sys/syscall-args index eca61683d7..f078081b87 100644 --- a/sys/sys/syscall-args +++ b/sys/sys/syscall-args @@ -1,8 +1,8 @@ # System call argument table. # DO NOT EDIT-- this file is automatically generated. -# $DragonFly: src/sys/sys/Attic/syscall-args,v 1.18 2005/08/27 20:23:05 joerg Exp $ +# $DragonFly: src/sys/sys/Attic/syscall-args,v 1.19 2005/11/16 02:24:33 dillon Exp $ -# Created from DragonFly: src/sys/kern/syscalls.master,v 1.26 2005/08/02 13:03:55 joerg Exp +# Created from DragonFly: src/sys/kern/syscalls.master,v 1.27 2005/08/27 20:23:05 joerg Exp int syscall nosys nosys_args void exit sys_exit sys_exit_args int rval @@ -262,3 +262,4 @@ int lstat lstat lstat_args const char * path struct stat * ub int fhstat fhstat fhstat_args const struct fhandle * u_fhp struct stat * sb int getdirentries getdirentries getdirentries_args int fd char * buf u_int count long * basep int getdents getdents getdents_args int fd char * buf size_t count +int usched_set usched_set usched_set_args const char * name int flags diff --git a/sys/sys/syscall-hide.h b/sys/sys/syscall-hide.h index 8edd5064a2..a196f7c120 100644 --- a/sys/sys/syscall-hide.h +++ b/sys/sys/syscall-hide.h @@ -2,8 +2,8 @@ * System call hiders. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/sys/syscall-hide.h,v 1.34 2005/08/27 20:23:05 joerg Exp $ - * created from DragonFly: src/sys/kern/syscalls.master,v 1.26 2005/08/02 13:03:55 joerg Exp + * $DragonFly: src/sys/sys/syscall-hide.h,v 1.35 2005/11/16 02:24:33 dillon Exp $ + * created from DragonFly: src/sys/kern/syscalls.master,v 1.27 2005/08/27 20:23:05 joerg Exp */ #ifdef COMPAT_43 @@ -309,3 +309,4 @@ HIDE_POSIX(lstat) HIDE_BSD(fhstat) HIDE_BSD(getdirentries) HIDE_BSD(getdents) +HIDE_BSD(usched_set) diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index 9785215029..3fed3af85e 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -2,8 +2,8 @@ * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/sys/syscall.h,v 1.34 2005/08/27 20:23:05 joerg Exp $ - * created from DragonFly: src/sys/kern/syscalls.master,v 1.26 2005/08/02 13:03:55 joerg Exp + * $DragonFly: src/sys/sys/syscall.h,v 1.35 2005/11/16 02:24:33 dillon Exp $ + * created from DragonFly: src/sys/kern/syscalls.master,v 1.27 2005/08/27 20:23:05 joerg Exp */ #define SYS_syscall 0 @@ -320,4 +320,5 @@ #define SYS_fhstat 478 #define SYS_getdirentries 479 #define SYS_getdents 480 -#define SYS_MAXSYSCALL 481 +#define SYS_usched_set 481 +#define SYS_MAXSYSCALL 482 diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index a79c373e93..b74666a732 100644 --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -1,7 +1,7 @@ # DragonFly system call names. # DO NOT EDIT-- this file is automatically generated. -# $DragonFly: src/sys/sys/syscall.mk,v 1.34 2005/08/27 20:23:05 joerg Exp $ -# created from DragonFly: src/sys/kern/syscalls.master,v 1.26 2005/08/02 13:03:55 joerg Exp +# $DragonFly: src/sys/sys/syscall.mk,v 1.35 2005/11/16 02:24:33 dillon Exp $ +# created from DragonFly: src/sys/kern/syscalls.master,v 1.27 2005/08/27 20:23:05 joerg Exp MIASM = \ syscall.o \ exit.o \ @@ -260,4 +260,5 @@ MIASM = \ lstat.o \ fhstat.o \ getdirentries.o \ - getdents.o + getdents.o \ + usched_set.o diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index 1c26c3237f..f836028ae7 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -2,8 +2,8 @@ * System call prototypes. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/sys/sysproto.h,v 1.34 2005/08/27 20:23:05 joerg Exp $ - * created from DragonFly: src/sys/kern/syscalls.master,v 1.26 2005/08/02 13:03:55 joerg Exp + * $DragonFly: src/sys/sys/sysproto.h,v 1.35 2005/11/16 02:24:33 dillon Exp $ + * created from DragonFly: src/sys/kern/syscalls.master,v 1.27 2005/08/27 20:23:05 joerg Exp */ #ifndef _SYS_SYSPROTO_H_ @@ -2187,6 +2187,14 @@ struct getdents_args { char * buf; char buf_[PAD_(char *)]; size_t count; char count_[PAD_(size_t)]; }; +struct usched_set_args { +#ifdef _KERNEL + struct sysmsg sysmsg; +#endif + union usrmsg usrmsg; + const char * name; char name_[PAD_(const char *)]; + int flags; char flags_[PAD_(int)]; +}; #ifdef COMPAT_43 @@ -2777,6 +2785,7 @@ int lstat (struct lstat_args *); int fhstat (struct fhstat_args *); int getdirentries (struct getdirentries_args *); int getdents (struct getdents_args *); +int usched_set (struct usched_set_args *); #endif /* !_SYS_SYSPROTO_H_ */ #undef PAD_ diff --git a/sys/sys/sysunion.h b/sys/sys/sysunion.h index f7e5e29ff9..bd288e3e10 100644 --- a/sys/sys/sysunion.h +++ b/sys/sys/sysunion.h @@ -2,8 +2,8 @@ * Union of syscall args for messaging. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/sys/sysunion.h,v 1.31 2005/08/27 20:23:05 joerg Exp $ - * created from DragonFly: src/sys/kern/syscalls.master,v 1.26 2005/08/02 13:03:55 joerg Exp + * $DragonFly: src/sys/sys/sysunion.h,v 1.32 2005/11/16 02:24:33 dillon Exp $ + * created from DragonFly: src/sys/kern/syscalls.master,v 1.27 2005/08/27 20:23:05 joerg Exp */ union sysunion { @@ -365,4 +365,5 @@ union sysunion { struct fhstat_args fhstat; struct getdirentries_args getdirentries; struct getdents_args getdents; + struct usched_set_args usched_set; }; diff --git a/sys/sys/usched.h b/sys/sys/usched.h index 0416016e89..aa36a61ee6 100644 --- a/sys/sys/usched.h +++ b/sys/sys/usched.h @@ -3,12 +3,14 @@ * * Userland scheduler API * - * $DragonFly: src/sys/sys/usched.h,v 1.6 2005/10/11 09:59:56 corecode Exp $ + * $DragonFly: src/sys/sys/usched.h,v 1.7 2005/11/16 02:24:33 dillon Exp $ */ #ifndef _SYS_USCHED_H_ #define _SYS_USCHED_H_ +#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES) + #ifndef _SYS_QUEUE_H_ #include #endif @@ -20,6 +22,8 @@ struct usched { TAILQ_ENTRY(usched) entry; const char *name; const char *desc; + void (*usched_register)(void); + void (*usched_unregister)(void); void (*acquire_curproc)(struct lwp *); void (*release_curproc)(struct lwp *); void (*select_curproc)(struct globaldata *); @@ -30,6 +34,7 @@ struct usched { void (*resetpriority)(struct lwp *); void (*heuristic_forking)(struct lwp *, struct lwp *); void (*heuristic_exiting)(struct lwp *, struct lwp *); + void (*setcpumask)(struct usched *, cpumask_t); }; union usched_data { @@ -47,7 +52,29 @@ union usched_data { int pad[4]; /* PAD for future expansion */ }; +/* + * Flags for usched_ctl() + */ +#define USCH_ADD 0x00000001 +#define USCH_REM 0x00000010 + +#endif /* _KERNEL || _KERNEL_STRUCTURES */ + +/* + * Kernel variables and procedures, or user system calls. + */ +#ifdef _KERNEL + extern struct usched usched_bsd4; +int usched_ctl(struct usched *, int); +struct usched *usched_init(void); + +#else + +int usched_set(const char *, int); + +#endif + #endif -- 2.41.0