tech-net archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
network synch bugs (was Re: ping: sendto: No buffer space available)
On Wed, Oct 05, 2011 at 10:27:03PM +0200, Thomas Klausner wrote:
> On Wed, Oct 05, 2011 at 09:44:30PM +0200, Thomas Klausner wrote:
> > When I start rtorrent with ~20 torrents and an effective traffic of a
> > few 100KB/s, after a short while the machine falls off the net. When I
> > do ping then, I see
> > ping: sendto: No buffer space available
>
> It's even worse, ral0 falls off the net with normal web browsing
> (well, opening 10 tabs in firefox in parallel, but that's not much...)
> ral0 at pci2 dev 2 function 0: Ralink Technologies RT2561S 802.11b/g
> (rev. 0x00)
> ral0: interrupting at ioapic1 pin 17
> ral0: 802.11 address 00:1f:1f:59:57:52
> ral0: MAC/BBP RT2561C, RF RT2527
> ral0: 11b rates: 1Mbps 2Mbps 5.5Mbps 11Mbps
> ral0: 11g rates: 1Mbps 2Mbps 5.5Mbps 11Mbps 6Mbps 9Mbps 12Mbps 18Mbps
> 24Mbps 36Mbps 48Mbps 54Mbps
This may have something to do with the way that I have botched
synchronization in net80211, and the way that somebody else has botched
synchronization of ifnet ioctls.
The attached (untested) patches may help.
Dave
--
David Young OJC Technologies is now Pixo
dyoung%pixotech.com@localhost Urbana, IL (217) 344-0444 x24
Index: if.c
===================================================================
RCS file: /cvsroot/src/sys/net/if.c,v
retrieving revision 1.251
diff -u -p -r1.251 if.c
--- if.c 12 Aug 2011 22:09:36 -0000 1.251
+++ if.c 5 Oct 2011 22:07:37 -0000
@@ -292,6 +293,9 @@ int
if_nullioctl(struct ifnet *ifp, u_long cmd, void *data)
{
+#ifdef straw_synch
+ cv_signal(&ifp->ifp_ioctl_emptied);
+#endif
return ENXIO;
}
@@ -497,8 +501,12 @@ if_attach(struct ifnet *ifp)
}
TAILQ_INIT(&ifp->if_addrlist);
TAILQ_INSERT_TAIL(&ifnet, ifp, if_list);
+#ifdef straw_synch
+ ifioctl_attach(ifp);
+#else
if (ifp->if_ioctl == NULL)
ifp->if_ioctl = ifioctl_common;
+#endif
mutex_enter(&index_gen_mtx);
ifp->if_index_gen = index_gen++;
@@ -842,6 +850,10 @@ again:
TAILQ_REMOVE(&ifnet, ifp, if_list);
+#ifdef straw_synch
+ ifioctl_detach(ifp);
+#endif
+
/*
* remove packets that came from ifp, from software interrupt queues.
*/
@@ -1801,11 +1824,16 @@ ifioctl(struct socket *so, u_long cmd, v
oif_flags = ifp->if_flags;
+#ifdef straw_synch
+ uint64_t nenter = percpu_getref(ifp->ifp_ioctl_nenter);
+ (*nenter)++;
+ mutex_enter(&ifp->ifp_ioctl_lock);
+#endif
error = (*ifp->if_ioctl)(ifp, cmd, data);
if (error != ENOTTY)
;
else if (so->so_proto == NULL)
- return EOPNOTSUPP;
+ error = EOPNOTSUPP;
else {
#ifdef COMPAT_OSOCK
error = compat_ifioctl(so, ocmd, cmd, data, l);
@@ -1830,9 +1858,59 @@ ifioctl(struct socket *so, u_long cmd, v
ifreqn2o(oifr, ifr);
#endif
+#ifdef straw_synch
+ ifp->ifp_ioctl_nexit++;
+ mutex_exit(&ifp->ifp_ioctl_lock);
+#endif
return error;
}
+#ifdef straw_synch
+static void
+ifioctl_sum(void *p, void *arg, struct cpu_info *ci)
+{
+ uint64_t *sum = arg, *nenter = p;
+
+ *sum += *nenter;
+}
+
+static uint64_t
+ifioctl_entrances(struct ifnet *ifp)
+{
+ uint64_t sum = 0;
+
+ percpu_foreach(ifp->ifp_ioctl_nenter, ifioctl_sum, &sum);
+
+ return sum;
+}
+
+int
+ifioctl_attach(struct ifnet *ifp)
+{
+ if (ifp->if_ioctl == NULL)
+ ifp->if_ioctl = ifioctl_common;
+
+ ifp->ifp_ioctl_nenter = percpu_alloc(sizeof(uint64_t));
+ if (ifp->ifp_ioctl_nenter == NULL)
+ return ENOMEM;
+
+ mutex_init(&ifp->ifp_ioctl_lock, MUTEX_DEFAULT, IPL_NONE);
+ cv_init(&ifp->ifp_ioctl_emptied, ifp->ifp_xname);
+
+ return 0;
+}
+
+void
+ifioctl_detach(struct ifnet *ifp)
+{
+ mutex_enter(&ifp->ifp_ioctl_lock);
+ ifp->if_ioctl = if_nullioctl;
+ while (ifioctl_entrances(ifp) != ifp->if_ioctl_nexit)
+ cv_wait(&ifp->ifp_ioctl_emptied, &ifp->ifp_ioctl_lock);
+ mutex_exit(&ifp->ifp_ioctl_lock);
+}
+#endif
+
/*
* Return interface configuration
* of system. List may be used
Index: if.h
===================================================================
RCS file: /cvsroot/src/sys/net/if.h,v
retrieving revision 1.151
diff -u -p -r1.151 if.h
--- if.h 12 Aug 2011 22:09:17 -0000 1.151
+++ if.h 5 Oct 2011 22:07:37 -0000
@@ -296,6 +300,12 @@ typedef struct ifnet {
* same, they are the same ifnet.
*/
struct sysctllog *if_sysctl_log;
+#ifdef straw_sched
+ kmutex_t if_ioctl_lock;
+ uint64_t if_ioctl_nexit;
+ percpu_t *if_ioctl_nenter;
+ kcondvar_t if_ioctl_emptied;
+#endif
} ifnet_t;
#define if_mtu if_data.ifi_mtu
? .ieee80211_netbsd.h.swp
Index: ieee80211_netbsd.c
===================================================================
RCS file: /cvsroot/src/sys/net80211/ieee80211_netbsd.c,v
retrieving revision 1.18
diff -u -p -r1.18 ieee80211_netbsd.c
--- ieee80211_netbsd.c 17 Jul 2011 20:54:52 -0000 1.18
+++ ieee80211_netbsd.c 5 Oct 2011 22:32:24 -0000
@@ -488,15 +488,11 @@ err:
int
ieee80211_node_dectestref(struct ieee80211_node *ni)
{
- int rc, s;
- s = splnet();
- if (--ni->ni_refcnt == 0) {
- rc = 1;
- ni->ni_refcnt = 1;
+ if (atomic_dec_uint_nv(&ni->ni_refcnt) == 0) {
+ atomic_inc_uint(&ni->ni_refcnt);
+ return 1;
} else
- rc = 0;
- splx(s);
- return rc;
+ return 0;
}
void
Index: ieee80211_netbsd.h
===================================================================
RCS file: /cvsroot/src/sys/net80211/ieee80211_netbsd.h,v
retrieving revision 1.15
diff -u -p -r1.15 ieee80211_netbsd.h
--- ieee80211_netbsd.h 15 Jun 2008 16:42:19 -0000 1.15
+++ ieee80211_netbsd.h 5 Oct 2011 22:32:24 -0000
@@ -30,6 +30,8 @@
#ifndef _NET80211_IEEE80211_NETBSD_H_
#define _NET80211_IEEE80211_NETBSD_H_
+#include <sys/atomic.h>
+
#ifdef _KERNEL
#define IASSERT(__cond, __complaint) \
do { \
@@ -167,9 +169,9 @@ typedef kmutex_t acl_lock_t;
#define ieee80211_node_initref(_ni) \
do { ((_ni)->ni_refcnt = 1); } while (0)
#define ieee80211_node_incref(_ni) \
- do { (_ni)->ni_refcnt++; } while (0)
+ atomic_inc_uint(&(_ni)->ni_refcnt)
#define ieee80211_node_decref(_ni) \
- do { (_ni)->ni_refcnt--; } while (0)
+ atomic_dec_uint(&(_ni)->ni_refcnt)
struct ieee80211_node;
int ieee80211_node_dectestref(struct ieee80211_node *ni);
#define ieee80211_node_refcnt(_ni) (_ni)->ni_refcnt
Home |
Main Index |
Thread Index |
Old Index