Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 6 Mar 2021 11:33:03 +0100
From:      Hans Petter Selasky <hps@selasky.org>
To:        "Alexander V. Chernikov" <melifaro@FreeBSD.org>, src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   Re: git: 600eade2fb4f - main - Add ifa_try_ref() to simplify ifa handling inside epoch.
Message-ID:  <938ca724-5f45-1d94-c22e-df348abdd030@selasky.org>
In-Reply-To: <202102162018.11GKIs1U039108@gitrepo.freebsd.org>
References:  <202102162018.11GKIs1U039108@gitrepo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On 2/16/21 9:18 PM, Alexander V. Chernikov wrote:
> The branch main has been updated by melifaro:
> 
> URL: https://cgit.FreeBSD.org/src/commit/?id=600eade2fb4faacfcd408a01140ef15f85f0c817
> 
> commit 600eade2fb4faacfcd408a01140ef15f85f0c817
> Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
> AuthorDate: 2021-02-16 20:12:58 +0000
> Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
> CommitDate: 2021-02-16 20:14:50 +0000
> 
>      Add ifa_try_ref() to simplify ifa handling inside epoch.
>      
>      More and more code migrates from lock-based protection to the NET_EPOCH
>       umbrella. It requires some logic changes, including, notably, refcount
>       handling.
>      
>      When we have an `ifa` pointer and we're running inside epoch we're
>       guaranteed that this pointer will not be freed.
>      However, the following case can still happen:
>       * in thread 1 we drop to 0 refcount for ifa and schedule its deletion.
>       * in thread 2 we use this ifa and reference it
>       * destroy callout kicks in
>       * unhappy user reports bug
>      
>      To address it, new `ifa_try_ref()` function is added, allowing to return
>       failure when we try to reference `ifa` with 0 refcount.
>      Additionally, existing `ifa_ref()` is enforced with `KASSERT` to provide
>       cleaner error in such scenarious.
>      
>      Reviewed By: rstone, donner
>      Differential Revision: https://reviews.freebsd.org/D28639
>      MFC after:      1 week
> ---
>   sys/net/if.c     | 12 +++++++++++-
>   sys/net/if_var.h |  1 +
>   2 files changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/sys/net/if.c b/sys/net/if.c
> index c85cfab19bf6..948be6876b65 100644
> --- a/sys/net/if.c
> +++ b/sys/net/if.c
> @@ -1857,8 +1857,18 @@ fail:
>   void
>   ifa_ref(struct ifaddr *ifa)
>   {
> +	u_int old;
>   
> -	refcount_acquire(&ifa->ifa_refcnt);
> +	old = refcount_acquire(&ifa->ifa_refcnt);
> +	KASSERT(old > 0, ("%s: ifa %p has 0 refs", __func__, ifa));
> +}
> +
> +int
> +ifa_try_ref(struct ifaddr *ifa)
> +{
> +
> +	NET_EPOCH_ASSERT();
> +	return (refcount_acquire_if_not_zero(&ifa->ifa_refcnt));
>   }
>   
>   static void
> diff --git a/sys/net/if_var.h b/sys/net/if_var.h
> index 9ecdfb684296..291a7781d73c 100644
> --- a/sys/net/if_var.h
> +++ b/sys/net/if_var.h
> @@ -577,6 +577,7 @@ struct ifaddr {
>   struct ifaddr *	ifa_alloc(size_t size, int flags);
>   void	ifa_free(struct ifaddr *ifa);
>   void	ifa_ref(struct ifaddr *ifa);
> +int	ifa_try_ref(struct ifaddr *ifa);

I think you should add __result_use_check for this prototype!?

--HPS



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?938ca724-5f45-1d94-c22e-df348abdd030>