Locking and module removal

Frodo Looijaard frodol en dds.nl
Mie Ene 26 19:32:26 CST 2000


Hi folks,

I have a general question about locking combined with module removal.
This question was triggered by trying to implement completely safe
locking for the I2C code, but it applies to other cases as well.

Imagine a kernel module that has several entry points. An entry point
could be a call from another related module (for example through a 
call-back function), a sysctl, /proc or /dev implementation function,
or possibly something else yet.

At a certain point, the module is to be removed so cleanup_module() is
called (the user has called rmmod(8) on this module, for example). So
we want to remove all allocated structures, entry points etc. So we
delete call-back function hooks, call remove_proc_entry(),
unregister_chrdev() etc. And then we want to remove allocated structures,
that are accessed through the entry points. But how to do that safely?

Imagine a 2-way SMP computer. While processor 1 is doing the 
cleanup_module() stuff, processor 2 may still be handling a /proc
request. That would be nasty. So we use a lock (semaphore):

  function handle_proc_request(...)
  {
    LOCK
    code... access stuff
    UNLOCK
  }

  function remove_module(...)
  {
    LOCK
    remove stuff
    UNLOCK 
    /* After returning, the kernel module is removed */
  }

But there are a couple of traps here. First off, processor 2 may encounter
the handle_proc_request LOCK *after* the remove_module LOCK has been set
by processor 1. So processor 2 waits until the lock is released, but at
that point, it should *not* be allowed to access the stuff that has been
removed! You could test for this, of course, by setting a flag 
code_has_removed_return_with_error. But that won't help in the next case:

Processor 1 enters remove_module and sets the lock. Processor 2 is
going to call handle_proc_request, but is delayed for some reason
(perhaps because it is still running the code that will do the call).
Now processor 1 does the remove_module and *removes the module*! At
that point, processor 2 is exactly at the { of the handle_proc_request
function. What will happen? Is this possible at all?

So the real problem is the (extremely small) window between the
entering of the function, and the execution of the LOCK, combined with
the fact that we want to remove the things that are accessed within the
locked region.

I am sure there are good ways to solve the above problem, but I don't
know them. Can anybody help me?

Thanks,
  Frodo

-- 
Frodo Looijaard <frodol en dds.nl>  PGP key and more: http://huizen.dds.nl/~frodol
Defenestration n. (formal or joc.):
  The act of removing Windows from your computer in disgust, usually followed
  by the installation of Linux or some other Unix-like operating system.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo en vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



Más información sobre la lista de distribución Ayuda