Linux-kernel mailing list archive 1999-23,: Re: Why isn't this a bug in run_bottom_halves() (2.2.5)?

# Re: Why isn't this a bug in run_bottom_halves() (2.2.5)?

B. James Phillippe (bryan@terran.org)
Sun, 6 Jun 1999 16:47:11 -0700 (PDT)

- Messages sorted by: [ date ][ thread ][ subject ][ author ]
- Next message: Steve Willer: "Re: RFC: Devices, buses and hotplug"
- Previous message: Bryn Paul Arnold Jones: "Re: FireWire subsystem in development"
- Maybe in reply to: Scott Maxwell: "Why isn't this a bug in run_bottom_halves() (2.2.5)?"

On Sun, 6 Jun 1999, Scott Maxwell wrote:

> Looking at the 2.2.5 kernel, I saw what seems to be a bug in
> run_bottom_halves(). The big fat comment describes my thinking:

I think I can explain what you are seeing. My comment follows yours:

> static inline void run_bottom_halves(void)
> {
> unsigned long active;
> void (**bh)(void);
>
> active = get_active_bhs();
> /*
> * Interrupts are enabled here. So suppose an interrupt occurs when
> * we're right here and its top half marks a previously unmarked
> * bottom half. do_IRQ() won't execute run_bottom_halves() after
> * servicing the new interrupt's top half because we already have the
> * lock for run_bottom_halves(), but when we return to this point, we
> * zero bh_active in the next line, so the newly marked BH never gets
> * run. I know we don't promise to service BHs right away (that's the
> * point), but we shouldn't overlook them entirely, right?
> */

/*
* But... active is a bitmask, atomically obtained by get_active_bhs. It
* is a snapshot copy of bh_active, saved on the local stack. Now as you
* suggest, a new top-half comes in and does a mark_bh on some arbitrary
* bottom-half, so bh_active now has some bit(s) set that wasn't when we
* did get_active_bhs. run_bottom_halves runs serially, so we won't come
* back here until we're completely done. However, when we do a
* clear_active_bhs, that only clears the bits of bh_active that were set
* in active when we did the get_active_bhs, also atomically. So only the
* bh's that were already active get cleared; new ones stay set. So when
* we come back here next time we'll get it then, along with any others
* that have been marked.
*/

> clear_active_bhs(active);
> bh = bh_base;
> do {
> if (active & 1)
> (*bh)();
> bh++;
> active >>= 1;
> } while (active);
> }

Tell me if this doesn't make any sense.

-bp

    --
    # Software Development, WatchGuard Inc.
    # Projects, PGP key at http://www.terran.org/~bryan

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

- Next message: Steve Willer: "Re: RFC: Devices, buses and hotplug"
- Previous message: Bryn Paul Arnold Jones: "Re: FireWire subsystem in development"
- Maybe in reply to: Scott Maxwell: "Why isn't this a bug in run_bottom_halves() (2.2.5)?"