I've got one ok for this.  Can I have another one please?

On Mon, Nov 24, 2014 at 13:54 +0100, Mike Belopuhov wrote:
> On Sun, Nov 23, 2014 at 12:06 +0100, Martin Pieuchot wrote:
> > On 23/11/14(Sun) 02:10, Mike Belopuhov wrote:
> > > Hi,
> > > 
> > > This removes the system wide if_slowtimo timeout and lets every
> > > interface with a valid if_watchdog method register it's own.
> > > The rational is to get rid of the ifnet loop in the softclock
> > > context to avoid further complications with concurrent access
> > > to the ifnet list.  This might also save some cpu cycles in the
> > > runtime if number of interfaces is large while only a fraction
> > > all of them have a watchdog routine.
> > > 
> > > This has originally come up on NetBSD mailing lists with some
> > > rather complicated locking strategy.  Masao Uebayashi has later
> > > proposed a similar solution.
> > > 
> > > The diff was looked at and corrected by mpi@.  I've tested the
> > > trunk and a system build as well.  OK?
> > 
> > I'm basically ok, some remarks below.
> > 
> > 
> > What about putting the allocation inside if_attach_common() with the
> > hooks that are allocated for the same reason?
> 
> Sure.
> 
> > Maybe we should explain why we allocate them?
> > 
> 
> We all know why, don't think it will help anything.
> 
> New version.  OK?
> 
> 
> diff --git sys/net/if.c sys/net/if.c
> index 0632eec..679c8c8 100644
> --- sys/net/if.c
> +++ sys/net/if.c
> @@ -133,11 +133,10 @@ void    if_attachdomain1(struct ifnet *);
>  void if_attach_common(struct ifnet *);
>  
>  void if_detach_queues(struct ifnet *, struct ifqueue *);
>  void if_detached_start(struct ifnet *);
>  int  if_detached_ioctl(struct ifnet *, u_long, caddr_t);
> -void if_detached_watchdog(struct ifnet *);
>  
>  int  if_getgroup(caddr_t, struct ifnet *);
>  int  if_getgroupmembers(caddr_t);
>  int  if_getgroupattribs(caddr_t);
>  int  if_setgroupattribs(caddr_t);
> @@ -169,16 +168,12 @@ int     net_livelocked(void);
>   * parameters.
>   */
>  void
>  ifinit()
>  {
> -     static struct timeout if_slowtim;
> -
> -     timeout_set(&if_slowtim, if_slowtimo, &if_slowtim);
>       timeout_set(&net_tick_to, net_tick, &net_tick_to);
>  
> -     if_slowtimo(&if_slowtim);
>       net_tick(&net_tick_to);
>  }
>  
>  static unsigned int if_index = 0;
>  static unsigned int if_indexlim = 0;
> @@ -270,10 +265,13 @@ if_attachsetup(struct ifnet *ifp)
>               if_attachdomain1(ifp);
>  #if NPF > 0
>       pfi_attach_ifnet(ifp);
>  #endif
>  
> +     timeout_set(ifp->if_slowtimo, if_slowtimo, ifp);
> +     if_slowtimo(ifp);
> +
>       /* Announce the interface. */
>       rt_ifannouncemsg(ifp, IFAN_ARRIVAL);
>  }
>  
>  /*
> @@ -426,10 +424,13 @@ if_attach_common(struct ifnet *ifp)
>           M_TEMP, M_WAITOK);
>       TAILQ_INIT(ifp->if_linkstatehooks);
>       ifp->if_detachhooks = malloc(sizeof(*ifp->if_detachhooks),
>           M_TEMP, M_WAITOK);
>       TAILQ_INIT(ifp->if_detachhooks);
> +
> +     ifp->if_slowtimo = malloc(sizeof(*ifp->if_slowtimo), M_TEMP,
> +         M_WAITOK|M_ZERO);
>  }
>  
>  void
>  if_start(struct ifnet *ifp)
>  {
> @@ -481,19 +482,22 @@ if_detach(struct ifnet *ifp)
>       struct domain *dp;
>  
>       ifp->if_flags &= ~IFF_OACTIVE;
>       ifp->if_start = if_detached_start;
>       ifp->if_ioctl = if_detached_ioctl;
> -     ifp->if_watchdog = if_detached_watchdog;
> +     ifp->if_watchdog = NULL;
>  
>       /*
>        * Call detach hooks from head to tail.  To make sure detach
>        * hooks are executed in the reverse order they were added, all
>        * the hooks have to be added to the head!
>        */
>       dohooks(ifp->if_detachhooks, HOOK_REMOVE | HOOK_FREE);
>  
> +     /* Remove the watchdog timeout */
> +     timeout_del(ifp->if_slowtimo);
> +
>  #if NBRIDGE > 0
>       /* Remove the interface from any bridge it is part of.  */
>       if (ifp->if_bridgeport)
>               bridge_ifdetach(ifp);
>  #endif
> @@ -577,10 +581,12 @@ do { \
>  
>       free(ifp->if_addrhooks, M_TEMP, 0);
>       free(ifp->if_linkstatehooks, M_TEMP, 0);
>       free(ifp->if_detachhooks, M_TEMP, 0);
>  
> +     free(ifp->if_slowtimo, M_TEMP, sizeof(*ifp->if_slowtimo));
> +
>       for (dp = domains; dp; dp = dp->dom_next) {
>               if (dp->dom_ifdetach && ifp->if_afdata[dp->dom_family])
>                       (*dp->dom_ifdetach)(ifp,
>                           ifp->if_afdata[dp->dom_family]);
>       }
> @@ -1160,29 +1166,26 @@ if_link_state_change_task(void *arg, void *unused)
>       }
>       splx(s);
>  }
>  
>  /*
> - * Handle interface watchdog timer routines.  Called
> - * from softclock, we decrement timers (if set) and
> + * Handle interface watchdog timer routine.  Called
> + * from softclock, we decrement timer (if set) and
>   * call the appropriate interface routine on expiration.
>   */
>  void
>  if_slowtimo(void *arg)
>  {
> -     struct timeout *to = (struct timeout *)arg;
> -     struct ifnet *ifp;
> +     struct ifnet *ifp = arg;
>       int s = splnet();
>  
> -     TAILQ_FOREACH(ifp, &ifnet, if_list) {
> -             if (ifp->if_timer == 0 || --ifp->if_timer)
> -                     continue;
> -             if (ifp->if_watchdog)
> +     if (ifp->if_watchdog) {
> +             if (ifp->if_timer > 0 && --ifp->if_timer == 0)
>                       (*ifp->if_watchdog)(ifp);
> +             timeout_add(ifp->if_slowtimo, hz / IFNET_SLOWHZ);
>       }
>       splx(s);
> -     timeout_add(to, hz / IFNET_SLOWHZ);
>  }
>  
>  /*
>   * Map interface name to interface structure pointer.
>   */
> @@ -1824,16 +1827,10 @@ int
>  if_detached_ioctl(struct ifnet *ifp, u_long a, caddr_t b)
>  {
>       return ENODEV;
>  }
>  
> -void
> -if_detached_watchdog(struct ifnet *ifp)
> -{
> -     /* nothing */
> -}
> -
>  /*
>   * Create interface group without members
>   */
>  struct ifg_group *
>  if_creategroup(const char *groupname)
> diff --git sys/net/if_trunk.c sys/net/if_trunk.c
> index 90e7fe9..c4bc760 100644
> --- sys/net/if_trunk.c
> +++ sys/net/if_trunk.c
> @@ -342,15 +342,17 @@ trunk_port_create(struct trunk_softc *tr, struct ifnet 
> *ifp)
>  
>       /* Change the interface type */
>       tp->tp_iftype = ifp->if_type;
>       ifp->if_type = IFT_IEEE8023ADLAG;
>       ifp->if_tp = (caddr_t)tp;
> -     tp->tp_watchdog = ifp->if_watchdog;
> -     ifp->if_watchdog = trunk_port_watchdog;
>       tp->tp_ioctl = ifp->if_ioctl;
>       ifp->if_ioctl = trunk_port_ioctl;
>  
> +     timeout_del(ifp->if_slowtimo);
> +     tp->tp_watchdog = ifp->if_watchdog;
> +     ifp->if_watchdog = trunk_port_watchdog;
> +
>       tp->tp_if = ifp;
>       tp->tp_trunk = tr;
>  
>       /* Save port link layer address */
>       bcopy(((struct arpcom *)ifp)->ac_enaddr, tp->tp_lladdr, ETHER_ADDR_LEN);
> @@ -463,10 +465,13 @@ trunk_port_destroy(struct trunk_port *tp)
>       free(tp, M_DEVBUF, 0);
>  
>       /* Update trunk capabilities */
>       tr->tr_capabilities = trunk_capabilities(tr);
>  
> +     /* Reestablish watchdog timeout */
> +     if_slowtimo(ifp);
> +
>       return (0);
>  }
>  
>  void
>  trunk_port_watchdog(struct ifnet *ifp)
> diff --git sys/net/if_var.h sys/net/if_var.h
> index cd40d8b..19f4f56 100644
> --- sys/net/if_var.h
> +++ sys/net/if_var.h
> @@ -70,10 +70,11 @@
>  
>  struct mbuf;
>  struct proc;
>  struct rtentry;
>  struct socket;
> +struct timeout;
>  struct ether_header;
>  struct arpcom;
>  struct rt_addrinfo;
>  struct ifnet;
>  struct hfsc_if;
> @@ -145,10 +146,11 @@ struct ifnet {                          /* and the 
> entries */
>       u_int32_t if_hardmtu;           /* maximum MTU device supports */
>       u_int   if_rdomain;             /* routing instance */
>       char    if_description[IFDESCRSIZE]; /* interface description */
>       u_short if_rtlabelid;           /* next route label */
>       u_int8_t if_priority;
> +     struct  timeout *if_slowtimo;   /* watchdog timeout */
>  
>       /* procedure handles */
>                                       /* output routine (enqueue) */
>       int     (*if_output)(struct ifnet *, struct mbuf *, struct sockaddr *,
>                    struct rtentry *);

Reply via email to