RE: [Bonding-devel] Re: Bonding driver unreliable under high CPU load
From: Jay Vosburgh <hidden>
Date: 2002-09-17 19:46:37
Actually, judging from how other drivers do this, the mii_ioctl_data
structure is really supposed to be assigned to &ifr.ifr_data. I dont
believe there is any storage where ifr_data points, and the ifr_ifru union
is 16 bytes, which is the size of the mii_ioctl_data structure.
-J
"Cureington, Tony" [off-list ref]@lists.sourceforge.net on
09/17/2002 12:28:52 PM
Sent by: bonding-devel-admin@lists.sourceforge.net
To: "Andrew Morton" <redacted>, "Pascal Brisset"
[off-list ref]
cc: <redacted>, <redacted>
Subject: RE: [Bonding-devel] Re: Bonding driver unreliable under high
CPU load
I've been running some similar code (on 2.4.18) that makes the ioctl a
macro - we must handle the MII ioctls too. The patch below also corrects
the mii pointer being assigned the address of a pointer (&ifr.ifr_data,
ifr_data is a macro that produces a pointer) instead of the pointer itself.
The patch:
--- linux-2.4.20-pre7/drivers/net/bonding.c Tue Sep 17 09:54:35 2002
+++ linux-2.4.20-pre7_mod/drivers/net/bonding.c Tue Sep 17 11:18:28 2002@@ -316,6 +316,28 @@ #define IS_UP(dev) ((((dev)->flags & (IFF_UP)) == (IFF_UP)) && \ (netif_running(dev) && netif_carrier_ok(dev))) +/* this IOCTL macro is used to prevent network drivers from returning -EFAULT + * from the ioctl, returning -EFAULT causes a link up status to be
returned
+ * from bond_check_dev_link even when the link is even connected. this
macro
+ * allows the get_user/copy_from_user in network drivers ioctls to work
without
+ * intermittently returning -EFAULT. this turns off argument validity
+ * checking on the address passed to the network driver ioctl.
+ *
+ * this method of turning off argument validity checking is also used in
the
+ * following drivers:
+ * /usr/src/linux/drivers/addon/iscsi/; addon/cpip; net/hamradio;
+ * net/wan; sound/;
+ *
+ * ioctl must be set to dev->do_ioctl before this macro
+ */
+#define IOCTL(dev, arg, cmd) ({ \
+ int ret; \
+ mm_segment_t fs = get_fs(); \
+ set_fs(get_ds()); \
+ ret = ioctl(dev, arg, cmd); \
+ set_fs(fs); \
+ ret; })
+
static void bond_restore_slave_flags(slave_t *slave)
{
slave->dev->flags = slave->original_flags;@@ -416,7 +438,7 @@ /* effect... */ etool.cmd = ETHTOOL_GLINK; ifr.ifr_data = (char*)&etool; - if (ioctl(dev, &ifr, SIOCETHTOOL) == 0) { + if (IOCTL(dev, &ifr, SIOCETHTOOL) == 0) { if (etool.data == 1) { return(MII_LINK_READY); }
@@ -431,13 +453,13 @@ */ /* Yes, the mii is overlaid on the ifreq.ifr_ifru */ - mii = (struct mii_ioctl_data *)&ifr.ifr_data; - if (ioctl(dev, &ifr, SIOCGMIIPHY) != 0) { + mii = (struct mii_ioctl_data *)ifr.ifr_data; + if (IOCTL(dev, &ifr, SIOCGMIIPHY) != 0) { return MII_LINK_READY; /* can't tell */ } mii->reg_num = 1; - if (ioctl(dev, &ifr, SIOCGMIIREG) == 0) { + if (IOCTL(dev, &ifr, SIOCGMIIREG) == 0) { /* * mii->val_out contains MII reg 1, BMSR * 0x0004 means link established
quoted hunk
-----Original Message----- From: Andrew Morton [mailto:akpm@digeo.com] Sent: Saturday, September 14, 2002 10:24 PM To: Pascal Brisset Cc: bonding-devel@lists.sourceforge.net; netdev@oss.sgi.com Subject: [Bonding-devel] Re: Bonding driver unreliable under high CPU load Pascal Brisset wrote:quoted
I would like to confirm the problem reported by Tony Cureington athttp://sourceforge.net/mailarchive/forum.php?thread_id=1015008 &forum_id=2094quoted
Problem: In MII-monitoring mode, when the CPU load is high, the ethernet bonding driver silently fails to detect dead links. How to reproduce: i686, 2.4.19; "modprobe bonding mode=1 miimon=100"; ifenslave two interfaces; ping while you plug/unplug cables. Bonding will switch to the available interface, as expected. Now load the CPU with "while(1) { }", and failover will not work at all anymore. Explanation: The bonding driver monitors the state of its slave interfaces by calling their dev->do_ioctl(SIOCGMIIREG|ETHTOOL_GLINK) from a timer callback function. Whenever this occurs during a user task, the get_user() in the ioctl handling code of the slave fails with -EFAULT because the ifreq struct is allocated in the stack of the timer function, above 0xC0000000. In that case, the bonding driver considers the link up by default. This problem went unnoticed because for most applications, when the active link dies, the host becomes idle and the monitoring function gets a chance to run during a kernel thread (in which caseit works).quoted
The active-backup switchover is just slower than it should be. Serious trouble only happens when the active link diesduring a long,quoted
CPU-intensive job. Is anyone working on a fix ? Maybe running the monitoring stuff in a dedicated task ?Running the ioctl in interrupt context is bad. Probably what should happen here is that the whole link monitoring function be pushed up to process context via a schedule_task() callout, or a do it in a dedicated kernel thread. This patch will probably make it work, but the slave device's ioctl simply isn't designed to be called from this context - it could try to take a semaphore, or a non-interrupt-safe lock or anything.--- linux-2.4.20-pre7/drivers/net/bonding.c Thu Sep 12 20:35:22 2002 +++ linux-akpm/drivers/net/bonding.c Sat Sep 14 20:23:45 2002@@ -208,6 +208,7 @@ #include <asm/io.h> #include <asm/dma.h> #include <asm/uaccess.h> +#include <asm/processor.h> #include <linux/errno.h> #include <linux/netdevice.h>@@ -401,6 +402,7 @@ static u16 bond_check_dev_link(struct ne struct ifreq ifr; struct mii_ioctl_data *mii; struct ethtool_value etool; + int ioctl_ret; if ((ioctl = dev->do_ioctl) != NULL) { /* ioctl toaccess MII */ /* TODO: set pointer to correct ioctl on a per team member */@@ -416,7 +418,13 @@ static u16 bond_check_dev_link(struct ne /* effect... */ etool.cmd = ETHTOOL_GLINK; ifr.ifr_data = (char*)&etool; - if (ioctl(dev, &ifr, SIOCETHTOOL) == 0) { + { + mm_segment_t old_fs = get_fs(); + set_fs(KERNEL_DS); + ioctl_ret = ioctl(dev, &ifr, SIOCETHTOOL); + set_fs(old_fs); + } + if (ioctl_ret == 0) { if (etool.data == 1) { return(MII_LINK_READY); } - -------------------------------------------------------This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf _______________________________________________ Bonding-devel mailing list Bonding-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bonding-devel
------------------------------------------------------- This SF.NET email is sponsored by: AMD - Your access to the experts on Hammer Technology! Open Source & Linux Developers, register now for the AMD Developer Symposium. Code: EX8664 http://www.developwithamd.com/developerlab _______________________________________________ Bonding-devel mailing list Bonding-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bonding-devel