lkml.org 
[lkml]   [2007]   [Apr]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 12/31] 8139too: RTNL and flush_scheduled_work deadlock
    -stable review patch.  If anyone has any objections, please let us know.

    ------------------
    From: Francois Romieu <romieu@fr.zoreil.com>

    Your usual dont-flush_scheduled_work-with-RTNL-held stuff.

    It is a bit different here since the thread runs permanently
    or is only occasionally kicked for recovery depending on the
    hardware revision.

    Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
    Cc: Ben Greear <greearb@candelatech.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    drivers/net/8139too.c | 40 +++++++++++++++++-----------------------
    1 file changed, 17 insertions(+), 23 deletions(-)

    --- a/drivers/net/8139too.c
    +++ b/drivers/net/8139too.c
    @@ -1109,6 +1109,8 @@ static void __devexit rtl8139_remove_one

    assert (dev != NULL);

    + flush_scheduled_work();
    +
    unregister_netdev (dev);

    __rtl8139_cleanup_dev (dev);
    @@ -1603,18 +1605,21 @@ static void rtl8139_thread (struct work_
    struct net_device *dev = tp->mii.dev;
    unsigned long thr_delay = next_tick;

    + rtnl_lock();
    +
    + if (!netif_running(dev))
    + goto out_unlock;
    +
    if (tp->watchdog_fired) {
    tp->watchdog_fired = 0;
    rtl8139_tx_timeout_task(work);
    - } else if (rtnl_trylock()) {
    - rtl8139_thread_iter (dev, tp, tp->mmio_addr);
    - rtnl_unlock ();
    - } else {
    - /* unlikely race. mitigate with fast poll. */
    - thr_delay = HZ / 2;
    - }
    + } else
    + rtl8139_thread_iter(dev, tp, tp->mmio_addr);

    - schedule_delayed_work(&tp->thread, thr_delay);
    + if (tp->have_thread)
    + schedule_delayed_work(&tp->thread, thr_delay);
    +out_unlock:
    + rtnl_unlock ();
    }

    static void rtl8139_start_thread(struct rtl8139_private *tp)
    @@ -1626,19 +1631,11 @@ static void rtl8139_start_thread(struct
    return;

    tp->have_thread = 1;
    + tp->watchdog_fired = 0;

    schedule_delayed_work(&tp->thread, next_tick);
    }

    -static void rtl8139_stop_thread(struct rtl8139_private *tp)
    -{
    - if (tp->have_thread) {
    - cancel_rearming_delayed_work(&tp->thread);
    - tp->have_thread = 0;
    - } else
    - flush_scheduled_work();
    -}
    -
    static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
    {
    tp->cur_tx = 0;
    @@ -1696,12 +1693,11 @@ static void rtl8139_tx_timeout (struct n
    {
    struct rtl8139_private *tp = netdev_priv(dev);

    + tp->watchdog_fired = 1;
    if (!tp->have_thread) {
    - INIT_DELAYED_WORK(&tp->thread, rtl8139_tx_timeout_task);
    + INIT_DELAYED_WORK(&tp->thread, rtl8139_thread);
    schedule_delayed_work(&tp->thread, next_tick);
    - } else
    - tp->watchdog_fired = 1;
    -
    + }
    }

    static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
    @@ -2233,8 +2229,6 @@ static int rtl8139_close (struct net_dev

    netif_stop_queue (dev);

    - rtl8139_stop_thread(tp);
    -
    if (netif_msg_ifdown(tp))
    printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",
    dev->name, RTL_R16 (IntrStatus));
    --
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2007-04-12 01:09    [W:0.036 / U:29.340 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site