CARP, no IPsec, Dell 1950 or NIC-less: boot crash, (uvm_fault)

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

CARP, no IPsec, Dell 1950 or NIC-less: boot crash, (uvm_fault)

chefren
CARP, no IPsec, Dell 1950 or NIC-less: boot crash

Our custom OpenBSD kernel crashes (uvm_fault) at boot on a Dell 1950.

We've tracked down the problem:
    carpattach()
        ...
        if_creategroup("carp")
            ...
            TAILQ_INSERT_TAIL(&ifg_head)

silently assumes that at least 1 'if_attach_common()' call has
happened by that point.

Dell 1950 has 'bnx' NICs, which delay attach until very late in kernel
boot (because of firmware load).

The 'enc' interface hides this bug in the stock kernel on Dell 1950,
and on computers without a NIC.

Easily reproduced with a stock kernel: 'boot -c', 'disable enc'

If a patch is appreciated by the maintainer, please don't hesitate to
mail me,

+++chefren

Reply | Threaded
Open this post in threaded view
|

Re: CARP, no IPsec, Dell 1950 or NIC-less: boot crash, (uvm_fault)

Bret S. Lambert-2
On Thu, Oct 21, 2010 at 11:28:51AM +0200, chefren wrote:

> CARP, no IPsec, Dell 1950 or NIC-less: boot crash
>
> Our custom OpenBSD kernel crashes (uvm_fault) at boot on a Dell 1950.
>
> We've tracked down the problem:
>     carpattach()
>         ...
>         if_creategroup("carp")
>             ...
>             TAILQ_INSERT_TAIL(&ifg_head)
>
> silently assumes that at least 1 'if_attach_common()' call has
> happened by that point.
>
> Dell 1950 has 'bnx' NICs, which delay attach until very late in kernel
> boot (because of firmware load).
>
> The 'enc' interface hides this bug in the stock kernel on Dell 1950,
> and on computers without a NIC.
>
> Easily reproduced with a stock kernel: 'boot -c', 'disable enc'
>
> If a patch is appreciated by the maintainer, please don't hesitate to
> mail me,
>
> +++chefren
>

Is the patch something like the following?


Index: if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.225
diff -u -p -r1.225 if.c
--- if.c 27 Aug 2010 17:08:01 -0000 1.225
+++ if.c 21 Oct 2010 10:44:19 -0000
@@ -161,7 +161,7 @@ RB_HEAD(ifaddr_items, ifaddr_item) ifadd
 RB_PROTOTYPE(ifaddr_items, ifaddr_item, ifai_entry, ifai_cmp);
 RB_GENERATE(ifaddr_items, ifaddr_item, ifai_entry, ifai_cmp);
 
-TAILQ_HEAD(, ifg_group) ifg_head;
+TAILQ_HEAD(, ifg_group) ifg_head = TAILQ_HEAD_INITIALIZER(ifg_head);
 LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners);
 int if_cloners_count;
 
@@ -190,7 +190,7 @@ static int if_index = 0;
 int if_indexlim = 0;
 struct ifaddr **ifnet_addrs = NULL;
 struct ifnet **ifindex2ifnet = NULL;
-struct ifnet_head ifnet;
+struct ifnet_head ifnet = TAILQ_HEAD_INITIALIZER(ifnet);
 struct ifnet_head iftxlist = TAILQ_HEAD_INITIALIZER(iftxlist);
 struct ifnet *lo0ifp;
 
@@ -443,10 +443,6 @@ void
 if_attach_common(struct ifnet *ifp)
 {
 
- if (if_index == 0) {
- TAILQ_INIT(&ifnet);
- TAILQ_INIT(&ifg_head);
- }
  TAILQ_INIT(&ifp->if_addrlist);
  ifp->if_addrhooks = malloc(sizeof(*ifp->if_addrhooks),
     M_TEMP, M_NOWAIT);

Reply | Threaded
Open this post in threaded view
|

Re: CARP, no IPsec, Dell 1950 or NIC-less: boot crash, (uvm_fault)

chefren
On 21-10-10 12:45, Bret S. Lambert wrote:

> Is the patch something like the following?

Looks right; tested: fixes the bug.

Thanks!

+++chefren


> Index: if.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if.c,v
> retrieving revision 1.225
> diff -u -p -r1.225 if.c
> --- if.c 27 Aug 2010 17:08:01 -0000 1.225
> +++ if.c 21 Oct 2010 10:44:19 -0000
> @@ -161,7 +161,7 @@ RB_HEAD(ifaddr_items, ifaddr_item) ifadd
>  RB_PROTOTYPE(ifaddr_items, ifaddr_item, ifai_entry, ifai_cmp);
>  RB_GENERATE(ifaddr_items, ifaddr_item, ifai_entry, ifai_cmp);
>  
> -TAILQ_HEAD(, ifg_group) ifg_head;
> +TAILQ_HEAD(, ifg_group) ifg_head = TAILQ_HEAD_INITIALIZER(ifg_head);
>  LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners);
>  int if_cloners_count;
>  
> @@ -190,7 +190,7 @@ static int if_index = 0;
>  int if_indexlim = 0;
>  struct ifaddr **ifnet_addrs = NULL;
>  struct ifnet **ifindex2ifnet = NULL;
> -struct ifnet_head ifnet;
> +struct ifnet_head ifnet = TAILQ_HEAD_INITIALIZER(ifnet);
>  struct ifnet_head iftxlist = TAILQ_HEAD_INITIALIZER(iftxlist);
>  struct ifnet *lo0ifp;
>  
> @@ -443,10 +443,6 @@ void
>  if_attach_common(struct ifnet *ifp)
>  {
>  
> - if (if_index == 0) {
> - TAILQ_INIT(&ifnet);
> - TAILQ_INIT(&ifg_head);
> - }
>   TAILQ_INIT(&ifp->if_addrlist);
>   ifp->if_addrhooks = malloc(sizeof(*ifp->if_addrhooks),
>      M_TEMP, M_NOWAIT);