tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kicking everybody out of the softc



I think this is already done for struct file (fo_restart).  First you
set a flag meaning the object is closing (== suspending, or "dying").
Driver code checks that flag in all entry points (including intr,
softint, callback).  If that flag is set, just return.  Thus any
thread can't enter the driver.

There may still exist busily running threads in the driver.  We can't
do much for them, so just wait for them to exit the driver.  Common
practice is to call cross-call (xc(9)) with NOP.  This ensures that
all CPUs execute a NOP function at least once.  Meaning that those
CPUs are no longer running in the driver.  Now you can safely shutdown
the driver.

To unload the driver, you have to ensure that no one has any reference
to the device.  I think this is done with reference counting.

Masao

On Mon, Aug 16, 2010 at 4:19 AM, David Young <dyoung%pobox.com@localhost> wrote:
> Currently, device detachment is racy: a kernel thread races to
> read/write a softc, after looking it up, before a second thread detaches
> the corresponding device_t and reclaims the softc's storage.  I've been
> working in spare moments on lockless code to prevent storage for a softc
> from going away while a driver uses it.  I submit the idea and the code
> here for review.
>
> To stop the races against detachment is tricky because many drivers
> are in and out of their softc over and over and over again, today,
> without any synchronization with detachment whatsoever.  To use
> atomic operations or locking to synchronize use of the softc with its
> reclamation can add costly locked memory transactions to many fast paths
> where there were no such transactions before, for a performance loss.
>
> I took an approach that avoids locked memory transactions in the
> common case.  I keep count of threads entering each softc on each
> CPU using per-CPU counters in the corresponding device_t: an LWP
> calls device_acquire(dev) as it enters a softc.  I also keep count
> of threads leaving each softc using per-CPU counters: an LWP calls
> device_release(dev) as it leaves a softc.  I call the counters
> "turnstiles."  Turnstile-counts only increase.  Because turnstiles
> are per-CPU, incrementing one only has to be atomic with respect to
> other threads on that same CPU, so no locked memory transactions are
> necessary.
>
> After a LWP enters a softc through its turnstile, it passes through a
> "gate" implemented by a pointer from the device_t to an object of type
> device_gate_t that contains a kernel mutex, among other things.  This
> happens in device_acquire().  Normally, the gate is open: the device_t
> points to the default device_gate_t, gate_open.  It is not necessary for
> device_acquire() to acquire gate_open's mutex, but device_acquire() must
> acquire every other gate's mutex.
>
> In the rare event that our thread wants to reclaim the softc (say that
> it is completing config_detach(9)), first it "closes the gate" on the
> softc's corresponding device_t.  To close the gate, our thread creates
> a closed device_gate_t, acquires its mutex, and points the device_t at
> it.  With the gate closed, our thread unlinks the device_t and softc.
> Finally, it "seals" the gate by pointing the device_t at a special
> device_gate_t, gate_sealed, and it wakes all of the threads that wait
> to acquire the closed gate's mutex.  Since the device_t and softc are
> unreachable, no new thread can enter them.  All of the threads that wake
> holding the closed gate see that the device_t now points to gate_sealed
> and leave the softc through a turnstile---device_acquire() returns in
> those threads with ENXIO.  Our thread safely reclaims the softc when the
> number of threads who have entered through its turnstiles balances the
> number who have left.
>
> Anyway, that's the gist of the idea.  I've attached the untested (and
> uncompiled) code for the details.  Comments?
>
> Dave
>
> [1] I'm using the term "thread" loosely to mean any thread of execution,
>    be it an LWP, software or hardware interrupt.
>
> --
> David Young             OJC Technologies
> dyoung%ojctech.com@localhost      Urbana, IL * (217) 278-3933
>


Home | Main Index | Thread Index | Old Index