http://perforce.freebsd.org/chv.cgi?CH=161793
Change 161793 by zec at zec_tpx32 on 2009/05/08 21:43:51
A controversial hack: when allocating if_unit numbers for
cloning ifnets, do NOT resort to bitmap mappings, but
iterate through all existing ifnets in a particular vnet
as long as a free unit number is found.
The problem here is that we are switchng from a O(n) to
a O(n**2) search method with more work being done in each
iteration. So this should be revisited RSN.
Affected files ...
.. //depot/projects/vimage-commit2/src/sys/net/if_clone.c#5 edit
Differences ...
==== //depot/projects/vimage-commit2/src/sys/net/if_clone.c#5 (text+ko) ====
@@ -401,6 +401,25 @@
* Find a free unit if none was given.
*/
if (wildcard) {
+#ifdef VIMAGE
+ /* XXX revisit - O(n**2) loop bellow! */
+ INIT_VNET_NET(curvnet);
+ char name[IFNAMSIZ];
+ struct ifnet *ifp;
+ int i = 0;
+
+ IFNET_RLOCK();
+again:
+ TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
+ sprintf(name, "%s%d", ifc->ifc_name, i);
+ if (strcmp(name, ifp->if_xname) == 0) {
+ i++;
+ goto again;
+ }
+ }
+ IFNET_RUNLOCK();
+ *unit = i;
+#else
while ((bytoff < ifc->ifc_bmlen)
&& (ifc->ifc_units[bytoff] == 0xff))
bytoff++;
@@ -411,6 +430,7 @@
while ((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0)
bitoff++;
*unit = (bytoff << 3) + bitoff;
+#endif
}
if (*unit > ifc->ifc_maxunit) {
@@ -418,6 +438,7 @@
goto done;
}
+#ifndef VIMAGE
if (!wildcard) {
bytoff = *unit >> 3;
bitoff = *unit - (bytoff << 3);
@@ -433,6 +454,7 @@
KASSERT((ifc->ifc_units[bytoff] & (1 << bitoff)) == 0,
("%s: bit is already set", __func__));
ifc->ifc_units[bytoff] |= (1 << bitoff);
+#endif
IF_CLONE_ADDREF_LOCKED(ifc);
done:
@@ -443,19 +465,22 @@
void
ifc_free_unit(struct if_clone *ifc, int unit)
{
+#ifndef VIMAGE
int bytoff, bitoff;
-
/*
* Compute offset in the bitmap and deallocate the unit.
*/
bytoff = unit >> 3;
bitoff = unit - (bytoff << 3);
+#endif
IF_CLONE_LOCK(ifc);
+#ifndef VIMAGE
KASSERT((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0,
("%s: bit is already cleared", __func__));
ifc->ifc_units[bytoff] &= ~(1 << bitoff);
+#endif
IF_CLONE_REMREF_LOCKED(ifc); /* releases lock */
}