[Click] [RESEND] [PATCH] Multithreading bug.
Joonwoo Park
joonwpark81 at gmail.com
Mon Oct 1 01:07:47 EDT 2007
The gmail demangled white spaces of the patch.
I'm resending a patch with another mail client.
Sorry.
Signed-off-by: Joonwoo Park <joonwpark81 at gmail.com>
---
elements/linuxmodule/todevice.cc | 46 +++++++++++++++++++++++++++++--------
elements/linuxmodule/todevice.hh | 2 +
2 files changed, 38 insertions(+), 10 deletions(-)
diff --git a/elements/linuxmodule/todevice.cc b/elements/linuxmodule/todevice.cc
index 35328ad..5ff53b5 100644
--- a/elements/linuxmodule/todevice.cc
+++ b/elements/linuxmodule/todevice.cc
@@ -267,8 +267,14 @@ ToDevice::run_task(Task *)
GET_STATS_RESET(low00, low10, time_now,
_perfcnt1_clean, _perfcnt2_clean, _time_clean);
# endif
- if (skbs)
+ if (skbs) {
+ // The dev_watchdog acquires dev->xmit_lock by timer interrupt.
+ // To avoid dead lock, we need to release dev->xmit_lock
+ // before calling skbmgr_recycle_skbs() - Joonwoo Park
+ xmit_unlock();
skbmgr_recycle_skbs(skbs);
+ xmit_lock();
+ }
# if CLICK_DEVICE_STATS
if (_activations > 0 && skbs)
GET_STATS_RESET(low00, low10, time_now,
@@ -345,15 +351,7 @@ ToDevice::run_task(Task *)
}
#endif
-#if LINUX_VERSION_CODE >= 0x020400
-# if HAVE_NETIF_TX_LOCK
- netif_tx_unlock_bh(_dev);
-# else
- _dev->xmit_lock_owner = -1;
- spin_unlock(&_dev->xmit_lock);
- local_bh_enable();
-# endif
-#endif
+ xmit_unlock();
// If we're polling, never go to sleep! We're relying on ToDevice to clean
// the transmit ring.
@@ -558,5 +556,33 @@ ToDevice::add_handlers()
add_task_handlers(&_task);
}
+inline void
+ToDevice::xmit_lock()
+{
+#if LINUX_VERSION_CODE >= 0x020400
+# if HAVE_NETIF_TX_LOCK
+ netif_tx_lock(_dev);
+# else
+ local_bh_disable();
+ spin_lock(&_dev->xmit_lock);
+ _dev->xmit_lock_owner = smp_processor_id();
+# endif
+#endif
+}
+
+inline void
+ToDevice::xmit_unlock()
+{
+#if LINUX_VERSION_CODE >= 0x020400
+# if HAVE_NETIF_TX_LOCK
+ netif_tx_unlock_bh(_dev);
+# else
+ _dev->xmit_lock_owner = -1;
+ spin_unlock(&_dev->xmit_lock);
+ local_bh_enable();
+# endif
+#endif
+}
+
ELEMENT_REQUIRES(AnyDevice linuxmodule)
EXPORT_ELEMENT(ToDevice)
diff --git a/elements/linuxmodule/todevice.hh b/elements/linuxmodule/todevice.hh
index 01aa264..0f53d95 100644
--- a/elements/linuxmodule/todevice.hh
+++ b/elements/linuxmodule/todevice.hh
@@ -159,6 +159,8 @@ class ToDevice : public AnyTaskDevice { public:
bool _no_pad;
int queue_packet(Packet *p);
+ inline void xmit_lock();
+ inline void xmit_unlock();
};
---
Joonwoo Park (Jason Park)
2007-09-27 (목), 16:58 +0900, Joonwoo Park wrote:
> Hi,
> Norbert reported previous patch didn't work.
> And I found a problem on ToDevice's::run_task().
>
> A new patch :
> The dev_watchdog acquires dev->xmit_lock by timer interrupt.
> To avoid dead lock, we need to release dev->xmit_lock before calling
> skbmgr_recycle_skbs().
> (disable && enable local_irq at RecycledSkbPool::lock() &&
> RecycledSkbPool::unlock() can be a alternative solution for this
> problem)
>
> Norbert, please let me know whether it works.
>
> -
> Signed-off-by: Joonwoo Park <joonwpark81 at gmail.com>
>
> elements/linuxmodule/todevice.cc | 46 +++++++++++++++++++++++++++++--------
> elements/linuxmodule/todevice.hh | 2 +
> 2 files changed, 38 insertions(+), 10 deletions(-)
>
> diff --git a/elements/linuxmodule/todevice.cc b/elements/linuxmodule/todevice.cc
> index 35328ad..5cb5d98 100644
> --- a/elements/linuxmodule/todevice.cc
> +++ b/elements/linuxmodule/todevice.cc
> @@ -267,8 +267,14 @@ ToDevice::run_task(Task *)
> GET_STATS_RESET(low00, low10, time_now,
> _perfcnt1_clean, _perfcnt2_clean, _time_clean);
> # endif
> - if (skbs)
> + if (skbs) {
> + // The dev_watchdog acquires dev->xmit_lock by timer interrupt.
> + // To avoid dead lock, we need to release dev->xmit_lock
> + // before calling skbmgr_recycle_skbs() - Joonwoo Park
> + xmit_unlock();
> skbmgr_recycle_skbs(skbs);
> + xmit_lock();
> + }
> # if CLICK_DEVICE_STATS
> if (_activations > 0 && skbs)
> GET_STATS_RESET(low00, low10, time_now,
> @@ -345,15 +351,7 @@ ToDevice::run_task(Task *)
> }
> #endif
>
> -#if LINUX_VERSION_CODE >= 0x020400
> -# if HAVE_NETIF_TX_LOCK
> - netif_tx_unlock_bh(_dev);
> -# else
> - _dev->xmit_lock_owner = -1;
> - spin_unlock(&_dev->xmit_lock);
> - local_bh_enable();
> -# endif
> -#endif
> + xmit_unlock();
>
> // If we're polling, never go to sleep! We're relying on ToDevice to clean
> // the transmit ring.
> @@ -558,5 +556,33 @@ ToDevice::add_handlers()
> add_task_handlers(&_task);
> }
>
> +inline void
> +ToDevice::xmit_lock()
> +{
> +#if LINUX_VERSION_CODE >= 0x020400
> +# if HAVE_NETIF_TX_LOCK
> + spin_lock_bh(&_dev->_xmit_lock);
> +# else
> + local_bh_disable();
> + spin_lock(&_dev->xmit_lock);
> + _dev->xmit_lock_owner = smp_processor_id();
> +# endif
> +#endif
> +}
> +
> +inline void
> +ToDevice::xmit_unlock()
> +{
> +#if LINUX_VERSION_CODE >= 0x020400
> +# if HAVE_NETIF_TX_LOCK
> + netif_tx_unlock_bh(_dev);
> +# else
> + _dev->xmit_lock_owner = -1;
> + spin_unlock(&_dev->xmit_lock);
> + local_bh_enable();
> +# endif
> +#endif
> +}
> +
> ELEMENT_REQUIRES(AnyDevice linuxmodule)
> EXPORT_ELEMENT(ToDevice)
> diff --git a/elements/linuxmodule/todevice.hh b/elements/linuxmodule/todevice.hh
> index 01aa264..0f53d95 100644
> --- a/elements/linuxmodule/todevice.hh
> +++ b/elements/linuxmodule/todevice.hh
> @@ -159,6 +159,8 @@ class ToDevice : public AnyTaskDevice { public:
> bool _no_pad;
>
> int queue_packet(Packet *p);
> + inline void xmit_lock();
> + inline void xmit_unlock();
>
> };
>
> -
>
> Joonwoo Park (Jason Park)
> _______________________________________________
> click mailing list
> click at amsterdam.lcs.mit.edu
> https://amsterdam.lcs.mit.edu/mailman/listinfo/click
More information about the click
mailing list