public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Rusty Russell <rusty@rustcorp.com.au>
To: linux-kernel@vger.kernel.org
Subject: Modules and the Interfaces who Love Them (Take I)
Date: Wed, 13 Nov 2002 21:17:22 +1100	[thread overview]
Message-ID: <20021113101924.104F92C0B0@lists.samba.org> (raw)

Feedback appreciated.  It's aimed at driver writers.
================
Documentation/module-writing.txt

Writing Modules and the Interfaces To Be Used By Them: A Gentle Guide.
Copyright 2002, Rusty Russell IBM Corportation

Modules are running parts of the kernel which can be added, and
sometimes removed, while the kernel is operational.

There are several delicate issues involved in this procedure which
indicate special care should be taken.

There are three cases you need to be careful:

1) Any code which creates an interface for callbacks (ie. almost any
   function called register_*)
	=> See Rule #1

2) Any modules which use (old) interfaces which do not obey Rule #1
	=> See Rule #2

Rule #1: Module-safe Interfaces.  Any interface which allows
	registration of callbacks, must also allow registration of a
	"struct module *owner", either in the structure or as a
	function parameter, and it must use them to protect the
	callbacks.  See "MAKING INTERFACES SAFE".

Exception #1: As an optimization, you may skip this protection if you
	   *know* that the callbacks are non-preemtible and never
	   sleep (eg. registration of interrupt handlers).


Rule #2: Modules using unsafe interfaces.  If your module is using any
	interface which does not obey rule number 1, that means your
	module functions may be called from the rest of the kernel
	without the caller first doing a successful try_module_get().

	You must not register a "module_cleanup" handler, and your module
	cannot be unloaded except by force.  You must be especially
	careful in this case with initialization: see "INITIALIZING
	MODULES WHICH USE UNSAFE INTERFACES".

MAKING INTERFACES SAFE

A caller must always call "try_module_get()" on a function pointers's
owner before calling through that function pointer.  If
"try_module_get()" returns 0 (false), the function pointer must *not*
be called, and the caller should pretend that registration does not
exist: this means the (module) owner is closing down and doesn't want
any more calls, or in the process of starting up and isn't ready yet.

For many interfaces, this can be optimized by assuming that a
structure containing function pointers has the same owner, and knowing
that one function is always called before the others, such as the
filesystem code which knows a mount must succeed before any other
methods can be accessed.

You must call "module_put()" on the owner sometime after you have
called the function(s).

If you cannot make your interface module-safe in this way, you can at
least split registration into a "reserve" stage and an "activate"
stage, so that modules can use the interface, even if they cannot
(easily) unload.


INITIALIZING MODULES WHICH USE UNSAFE INTERFACES

Safe interfaces will never enter your module before module_init() has
successfully finished, but unsafe interfaces may.  The rule is simple:
your init_module() function *must* succeed (by returning 0) if it has
successfully used any unsafe interfaces.

So, if you are only using ONE unsafe interface, simply use that
interface last.  Otherwise you will have to use printk() to report
failure and leave the module initialized (but possibly useless).


If you have questions about how to apply this document to your own
modules, please ask rusty@rustcorp.com.au or linux-kernel@vger.kernel.org.

Thankyou,
Rusty.
--
  Anyone who quotes me in their sig is an idiot. -- Rusty Russell.

             reply	other threads:[~2002-11-13 10:12 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-11-13 10:17 Rusty Russell [this message]
2002-11-13 19:02 ` Modules and the Interfaces who Love Them (Take I) Roman Zippel
2002-11-14  3:34   ` Rusty Russell
2002-11-14  4:34     ` Jeff Garzik
2002-11-14 10:28     ` Roman Zippel
2002-11-14 11:00     ` Roman Zippel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20021113101924.104F92C0B0@lists.samba.org \
    --to=rusty@rustcorp.com.au \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox