tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: vlan(4) mpsafe



Hi,

Thank you for comments.

I modify and rebase the patch.
Here is the updated patch:

https://gist.githubusercontent.com/s-ymgch228/02bb360cfd4e95eb1f64a66c28b30ab2/raw/1b9c8408da88a205ee1b09482125dcf49d5a762e/vlan_mpsafe.patch

> I don't have time for a detailed review right now, but here are some
> quick comments from a cursory glance.  First, this change introduces
> several new locks -- struct ifvlan::ifv_lock, ifv_list.lock, and
> ifv_hash.lock.  Can you write down a lock order for them?

I added the comments about locking notes and locking order into
if_vlanvar.h

> @@ -115,6 +122,21 @@ __KERNEL_RCSID(0, "$NetBSD: if_vlan.c,v 1.96 2017/03/15 09:51:08 ozaki-r Exp $")
>
>      #include "ioconf.h"
>
>     +#ifdef NET_MPSAFE
>     +#define VLAN_MPSAFE            1
>     +#define DECLARE_LOCK_VARIABLE
>     +#define ACQUIRE_GLOBAL_LOCKS() do { } while (0)
>     +#define RELEASE_GLOBAL_LOCKS() do { } while (0)
>     +#else
>     +#define DECLARE_LOCK_VARIABLE  int __s
>     +#define ACQUIRE_GLOBAL_LOCKS() do {                    \
>     +                                       __s = splnet(); \
>     +                               } while (0)
>     +#define RELEASE_GLOBAL_LOCKS() do {                    \
>     +                                       splx(__s);      \
>     +                               } while (0)
>     +#endif
>
> Is this necessary?  Can we just eliminate the splnet altogether yet?
> The name `global locks' is confusing -- splnet only blocks interrupts
> on the current CPU.

No, it isn't. All splnet can be eliminated because all data is protected
by locks newly introduced. In the updated patch, they are eliminated.

>     +vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t tag)
>      {
>     ...
>     +       mutex_enter(&ifv->ifv_lock);
>     ...
>     +       nmib = kmem_alloc(sizeof(*nmib), KM_SLEEP);
>     +       *nmib = *omib;
>
> Using kmem_* under a lock is not generally allowed.  You should
> preallocate the structure, and then acquire the lock.  In the error
> branch this may require you to free it immediately, but that's OK.

I didn't know such a restriction. I moved kmem_* before mutex_enter() or
after mutex_exit().

> @@ -370,33 +484,67 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p)
>              * to participate in bridges of that type.
>              */
>             ifv->ifv_if.if_type = p->if_type;
>     +       membar_producer();
>
>     -       return (0);
>     +       idx = tag_hash_func(tag, ifv_hash.mask);
>     +
>     +       mutex_enter(&ifv_hash.lock);
> + PSLIST_WRITER_INSERT_HEAD(&ifv_hash.lists[idx], ifv, ifv_hash);
>     +       mutex_exit(&ifv_hash.lock);
>     +
>     +       vlan_linkmib_update(ifv, nmib);
>     +       nmib = NULL;
>     +       kmem_free(omib, sizeof(*omib));
>
> This change is a little confusing.  I think you added the
> membar_producer here so that the content of nmib would be published
> before vlan_linkmib_update publishes the nmib pointer with
> ifv->ifv_mib = nmib.  In this case, the membar_producer is not
> *strictly* necessary because PSLIST_WRITER_INSERT_HEAD already issues
> one.
>
> But membars should generally come in pairs -- pretty much every
> membar_(datadep_)consumer should be paired with a corresponding
> membar_producer -- so it's best to make it very clear which ones match
> up.  So I would suggest that you either
>
> (a) add a comment saying that this membar_producer corresponds to the
> membar_datadep_consumer issued after reading ifv->ifv_mib; or
>
> (b) omit the membar_producer, and add a comment explaining that the
> membar_producer implied by PSLIST_WRITER_INSERT_HEAD works to match
> the membar_datadep_consumer; or
>
> (c) move the explicit membar_producer into vlan_linkmib_update.
>
> It took me about three readings to realize what was going on here, so
> the added clarity of any one of these options will make it easier to
> audit!

I selected (c) to fix this part in the updated patch.


Thanks,

--
Internet Initiative Japan Inc.

Device Engineering Section,
IoT Platform Development Department,
Network Division,
Technology Unit

Shoichi YAMAGUCHI <s-yamaguchi%iij.ad.jp@localhost>


Home | Main Index | Thread Index | Old Index