CONFIG_INTRHOOK(9)

πŸ’– CONFIG_INTRHOOK(9) πŸ’–

okay bestie, welcome to the config_intrhook page from the Kernel Developer's Manual β€” yes it's a section 9 page, yes it's kernel dev stuff, and yes you're gonna understand it, because I refuse to let you struggle 🫢


✨ NAME ✨

config_intrhook β€” schedule a function to be run after interrupts have been enabled, but before root is mounted

like. that's the whole vibe. you're queuing up a lil callback for that one specific window in boot where interrupts are live but root isn't mounted yet 🌸


✨ SYNOPSIS ✨

#include <sys/kernel.h>

typedef void (*ich_func_t)(void *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);

✨ DESCRIPTION ✨

so config_intrhook_establish() schedules a function to run after interrupts have been enabled, but before root is mounted ✨. and if the system has already blown past that point in its initialization? the function just gets called immediately, no waiting, instant main character energy πŸ‘‘

config_intrhook_disestablish() takes that entry and removes it from the hook queue. bye bestie πŸ’…

config_intrhook_oneshot() schedules a function exactly like config_intrhook_establish() does β€” same window, same deal β€” except the entry automatically removes itself from the hook queue once that function has run πŸŽ€. this one's perfect when you need extra device configuration done after interrupts are enabled but you literally do not need to stall the boot process afterwards. it's giving one-and-done, no cap.

⚠️ heads up though: config_intrhook_oneshot() allocates memory using M_WAITOK β€” so do not call this while holding any non-sleepable locks. seriously. don't. 😭

🌈 how the whole queue actually goes down

before root is mounted, all the previously established hooks get run. then the boot process stalls until every single handler removes its hook from the hook queue using config_intrhook_disestablish() πŸ¦‹. after that, boot proceeds and tries to mount the root file system.

so like β€” any driver that can potentially provide devices you'd wanna mount as root must either use this hook, or probe all those devices during the initial probe. because interrupts are disabled during the probe process, a lot of drivers need a way to probe for devices with interrupts enabled. that's the whole reason this exists. iykyk 🌸


🌟 the struct

the requests are made with the intr_config_hook structure, defined like this:

struct intr_config_hook {
        TAILQ_ENTRY(intr_config_hook) ich_links;/* Private */
        ich_func_t      ich_func;               /* function to call */
        void            *ich_arg;               /* Argument to call */
};

storage for the intr_config_hook structure must be provided by the driver πŸ‘‘. and it has to stay stable from just before the hook is established all the way until after the hook is disestablished. don't be moving it around mid-flight, that's not the move πŸ’€


⭐ the timing, exactly

specifically, hooks are run at SI_SUB_INT_CONFIG_HOOKS() β€” which is immediately after the scheduler is started, and just before the root file system device is discovered. that's the moment. that's the window. periodt ✨


✨ RETURN VALUES ✨

  • a zero return value means the hook was successfully added to the queue β€” could be either deferred or immediate execution, both count πŸ’–
  • a non-zero return value means the hook could not be added to the queue, because it was already on the queue πŸ™ˆ

✨ SEE ALSO ✨


✨ HISTORY ✨

these functions were introduced in FreeBSD 3.0 alongside the CAM subsystem β€” but bestie, they're available for any driver to use 🌈


✨ AUTHORS ✨

  • the functions were written by Justin Gibbs <gibbs@FreeBSD.org> πŸŽ€
  • this manual page was written by M. Warner Losh <imp@FreeBSD.org> πŸ’œ

and that's the page!! πŸ’… this one came out of Debian, dated August 10, 2017, and yeah it's still wearing the CONFIG_INTRHOOK(9) name tag πŸŽ€ β€” go forth and hook your interrupts responsibly, bestie 🫢✨

πŸ“¦ where this page comes from