From owner-svn-src-all@freebsd.org Sun Aug 13 18:10:25 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id EE5A2DCF875; Sun, 13 Aug 2017 18:10:25 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C76277CD54; Sun, 13 Aug 2017 18:10:25 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v7DIAOZc094570; Sun, 13 Aug 2017 18:10:24 GMT (envelope-from ian@FreeBSD.org) Received: (from ian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v7DIAOYi094566; Sun, 13 Aug 2017 18:10:24 GMT (envelope-from ian@FreeBSD.org) Message-Id: <201708131810.v7DIAOYi094566@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ian set sender to ian@FreeBSD.org using -f From: Ian Lepore Date: Sun, 13 Aug 2017 18:10:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r322465 - in head: share/man/man9 sys/kern sys/sys X-SVN-Group: head X-SVN-Commit-Author: ian X-SVN-Commit-Paths: in head: share/man/man9 sys/kern sys/sys X-SVN-Commit-Revision: 322465 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 Aug 2017 18:10:26 -0000 Author: ian Date: Sun Aug 13 18:10:24 2017 New Revision: 322465 URL: https://svnweb.freebsd.org/changeset/base/322465 Log: Add config_intrhook_oneshot(): schedule an intrhook function and unregister it automatically after it runs. The config_intrhook mechanism allows a driver to stall the boot process until device(s) required for booting are available, by not allowing system inits to proceed until all intrhook functions have been unregistered. Virtually all existing code simply unregisters from within the hook function when it gets called. This new function makes that common usage more convenient. Instead of allocating and filling in a struct, passing it to a function that might (in theory) fail, and checking the return code, now a driver can simply call this cannot-fail routine, passing just the intrhook function and its arg. Differential Revision: https://reviews.freebsd.org/D11963 Modified: head/share/man/man9/Makefile head/share/man/man9/config_intrhook.9 head/sys/kern/subr_autoconf.c head/sys/sys/kernel.h Modified: head/share/man/man9/Makefile ============================================================================== --- head/share/man/man9/Makefile Sun Aug 13 18:09:22 2017 (r322464) +++ head/share/man/man9/Makefile Sun Aug 13 18:10:24 2017 (r322465) @@ -669,7 +669,8 @@ MLINKS+=condvar.9 cv_broadcast.9 \ condvar.9 cv_wait_unlock.9 \ condvar.9 cv_wmesg.9 MLINKS+=config_intrhook.9 config_intrhook_disestablish.9 \ - config_intrhook.9 config_intrhook_establish.9 + config_intrhook.9 config_intrhook_establish.9 \ + config_intrhook.9 config_intrhook_oneshot.9 MLINKS+=contigmalloc.9 contigfree.9 MLINKS+=casuword.9 casueword.9 \ casuword.9 casueword32.9 \ Modified: head/share/man/man9/config_intrhook.9 ============================================================================== --- head/share/man/man9/config_intrhook.9 Sun Aug 13 18:09:22 2017 (r322464) +++ head/share/man/man9/config_intrhook.9 Sun Aug 13 18:10:24 2017 (r322465) @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 24, 2006 +.Dd August 10, 2017 .Dt CONFIG_INTRHOOK 9 .Os .Sh NAME @@ -35,10 +35,13 @@ but before root is mounted .Sh SYNOPSIS .In sys/kernel.h +.Vt typedef void (*ich_func_t)(void *arg); .Ft int .Fn config_intrhook_establish "struct intr_config_hook *hook" .Ft void .Fn config_intrhook_disestablish "struct intr_config_hook *hook" +.Ft void +.Fn config_intrhook_oneshot "ich_func_t func" "void *arg" .Sh DESCRIPTION The .Fn config_intrhook_establish @@ -51,6 +54,18 @@ The .Fn config_intrhook_disestablish function removes the entry from the hook queue. .Pp +The +.Fn config_intrhook_oneshot +function schedules a function to be run as described for +.Fn config_intrhook_establish ; +the entry is automatically removed from the hook queue +after that function runs. +This is appropriate when additional device configuration must be done +after interrupts are enabled, but there is no need to stall the +boot process after that. +This function allocates memory using M_WAITOK; do not call this while +holding any non-sleepable locks. +.Pp Before root is mounted, all the previously established hooks are run. The boot process is then stalled until all handlers remove their hook @@ -71,8 +86,8 @@ This structure is defined as follows: .Bd -literal struct intr_config_hook { TAILQ_ENTRY(intr_config_hook) ich_links;/* Private */ - void (*ich_func)(void *arg); /* function to call */ - void *ich_arg; /* Argument to call */ + ich_func_t ich_func; /* function to call */ + void *ich_arg; /* Argument to call */ }; .Ed .Pp Modified: head/sys/kern/subr_autoconf.c ============================================================================== --- head/sys/kern/subr_autoconf.c Sun Aug 13 18:09:22 2017 (r322464) +++ head/sys/kern/subr_autoconf.c Sun Aug 13 18:10:24 2017 (r322465) @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -63,6 +64,27 @@ MTX_SYSINIT(intr_config_hook, &intr_config_hook_lock, static void run_interrupt_driven_config_hooks(void); /* + * Private data and a shim function for implementing config_interhook_oneshot(). + */ +struct oneshot_config_hook { + struct intr_config_hook + och_hook; /* Must be first */ + ich_func_t och_func; + void *och_arg; +}; + +static void +config_intrhook_oneshot_func(void *arg) +{ + struct oneshot_config_hook *ohook; + + ohook = arg; + ohook->och_func(ohook->och_arg); + config_intrhook_disestablish(&ohook->och_hook); + free(ohook, M_DEVBUF); +} + +/* * If we wait too long for an interrupt-driven config hook to return, print * a diagnostic. */ @@ -181,6 +203,22 @@ config_intrhook_establish(struct intr_config_hook *hoo /* XXX Sufficient for modules loaded after initial config??? */ run_interrupt_driven_config_hooks(); return (0); +} + +/* + * Register a hook function that is automatically unregistered after it runs. + */ +void +config_intrhook_oneshot(ich_func_t func, void *arg) +{ + struct oneshot_config_hook *ohook; + + ohook = malloc(sizeof(*ohook), M_DEVBUF, M_WAITOK); + ohook->och_func = func; + ohook->och_arg = arg; + ohook->och_hook.ich_func = config_intrhook_oneshot_func; + ohook->och_hook.ich_arg = ohook; + config_intrhook_establish(&ohook->och_hook); } void Modified: head/sys/sys/kernel.h ============================================================================== --- head/sys/sys/kernel.h Sun Aug 13 18:09:22 2017 (r322464) +++ head/sys/sys/kernel.h Sun Aug 13 18:10:24 2017 (r322465) @@ -400,13 +400,16 @@ struct tunable_str { #define TUNABLE_STR_FETCH(path, var, size) \ getenv_string((path), (var), (size)) +typedef void (*ich_func_t)(void *_arg); + struct intr_config_hook { TAILQ_ENTRY(intr_config_hook) ich_links; - void (*ich_func)(void *arg); - void *ich_arg; + ich_func_t ich_func; + void *ich_arg; }; int config_intrhook_establish(struct intr_config_hook *hook); void config_intrhook_disestablish(struct intr_config_hook *hook); +void config_intrhook_oneshot(ich_func_t _func, void *_arg); #endif /* !_SYS_KERNEL_H_*/