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

Re: [PATCH v3 1/6] xen: add reference counter support


  • To: Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • From: Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Date: Thu, 16 Mar 2023 14:54:46 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=y9ZW+mhCQ5QSmZ9Jx0EC2aHMzN5S3uJ6UWnJzJkSE4M=; b=Vcmbl8mHXLfBJRz7ImBc34UAnKCb1MQvihwAlVNuDEWm3SUYSk1Enz73uXrGMJ/V4EkTf2PmMJlX3cF+3kht9CjX8WWbOJViOH3/n3T4aue9pdA/m1F2rFF+8uy5ugAD8VM9eoAL3FndZuIyCkZGEOvz5iaQpZ2jOyzR0gRYB1b9E79ZaVPx5ct92pkGscGajulW1vix34sqNIrECeDu80qOS16dzCufV0+fJRNGLwPJkWRq0PhbMauP3ekht7T6DI5cGKi7ULXNq2utCbF2h2Nam2gpiN/yAPct1AGXmZ3AQfUYLdebc1Fe9GMaRUyBLMceZwdj581w0AyUlvRzLw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=KHBbqZK0d+lMeK2sDxEhV5VgWgdP72mYrLpbzgS4WeT0S4Dg1cas3GyzOuHbFlyu6s4UGsoktwTdVCLOieesMyU4ixdqWeP/aIWnbZ2AKhDC1yk2/VUXkF5NE2hwekrEC1jCD8yffGw/3IBmvH3Y1BBEmi2pdmpTKkTMe5/QBy4lWwxp5wDd6TLR4F5sokYurPSmF5jBrQ5760EHe4m/hBSZLUEYerO/4mlBEdoRMao1ou58csGgOtA76ARcpQBHDNfIximSIr24cJlf1R1ACynOgKyZ3WSKmXgfTh0ugfoSFaJOVJKTyevnW70AeejKxP05bj939ipvzxuuMpvS+Q==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Cc: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, George Dunlap <george.dunlap@xxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Julien Grall <julien@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>
  • Delivery-date: Thu, 16 Mar 2023 13:55:35 +0000
  • Ironport-data: A9a23:jAI+ba2lp5PjhtmkjfbD5T5wkn2cJEfYwER7XKvMYLTBsI5bp2QBm jFKX2yCOfuOYmSjeNsjbIjg8kIP68OGndVqGwNvpC1hF35El5HIVI+TRqvS04F+DeWYFR46s J9OAjXkBJppJpMJjk71atANlVEliefTAOK6ULWeUsxIbVcMYD87jh5+kPIOjIdtgNyoayuAo tq3qMDEULOf82cc3lk8tuTS+HuDgNyo4GlD5gdnO6gU1LPjvyJ94Kw3dPnZw0TQGuG4LsbiL 87fwbew+H/u/htFIrtJRZ6iLyXm6paLVeS/oiI+t5qK23CulQRrukoPD9IOaF8/ttm8t4sZJ OOhF3CHYVxB0qXkwIzxWvTDes10FfUuFLTveRBTvSEPpqFvnrSFL/hGVSkL0YMkFulfIEVzq 98yBDUxVQ2N3vmcy4v8Uu42mZF2RCXrFNt3VnBI6xj8VK9jbbWdBqLA6JlfwSs6gd1IEbDGf c0FZDFzbRPGJRpSJlMQD5F4l+Ct7pX9W2QA9BTJ+uxqvC6Kk1QZPLvFabI5fvSQQspYhACAr 3/u9GXlGBAKcteYzFJp91r13raWx3mgAd56+LuQ7e96mwWrlkooOjo4X16gpLrihVyQcocKQ 6AT0m90xUQoz2SVSd36Uwy9sWSzlBcWUNpNEMU38AiIjKHT5m6xFmUCCzJMdtEinMs3XiAxk E+EmcvzAj5iu6HTTmiSnp+Wpz6vPSkeLUcZeDQJCwAC5rHLopw3jx/JZsZuFuiylNKdMSrr3 zmAoSw6hrMSpc0GzaO2+RbAmT3EjofNZh444EPQRG3N0+9iTIusZojt5V2F6/9Fdd+dVgPY4 yBCnNWC5ucTC53LjDaKXOgGALCu4bCCLSHYhllsWZIm8lxB5kKeQGyZ2xkmTG8BDyrOUWW2C KMPkWu9PKNuAUY=
  • Ironport-hdrordr: A9a23:iKYs4a5HmeTALl2ZeQPXwDjXdLJyesId70hD6qkQc3Fom62j5q STdZEgvyMc5wx/ZJhNo7690cq7MBbhHPxOkOos1N6ZNWGLhILPFuBfBOPZqAEIcBeOlNK1u5 0BT0EEMqyWMbB75/yKnDVREbwbsaa6GHbDv5ah859vJzsaGp2J921Ce2Cm+tUdfng9OXI+fq Dsn/Zvln6bVlk8SN+0PXUBV/irnay3qHq3CSR2fyLO8WO1/EiV1II=
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On Tue, Mar 14, 2023 at 08:56:29PM +0000, Volodymyr Babchuk wrote:
> We can use reference counter to ease up object lifetime management.
> This patch adds very basic support for reference counters. refcnt
> should be used in the following way:
> 
> 1. Protected structure should have refcnt_t field
> 
> 2. This field should be initialized with refcnt_init() during object
> construction.
> 
> 3. If code holds a valid pointer to a structure/object it can increase
> refcount with refcnt_get(). No additional locking is required.
> 
> 4. Code should call refcnt_put() before dropping pointer to a
> protected structure. `destructor` is a call back function that should
> destruct object and free all resources, including structure protected
> itself. Destructor will be called if reference counter reaches zero.
> 
> 5. If code does not hold a valid pointer to a protected structure it
> should use other locking mechanism to obtain a pointer. For example,
> it should lock a list that hold protected objects.

Sorry, I didn't look at the previous versions, but did we consider
importing refcount_t and related logic from Linux?

> 
> Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@xxxxxxxx>
> 
> ---
> v3:
>   - moved in from another patch series
>   - used structure to encapsulate refcnt_t
>   - removed #ifndef NDEBUG in favor of just calling ASSERT
>   - added assertion to refcnt_put
>   - added saturation support: code catches overflow and underflow
>   - added EMACS magic at end of the file
>   - fixed formatting
> ---
>  xen/include/xen/refcnt.h | 59 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 59 insertions(+)
>  create mode 100644 xen/include/xen/refcnt.h
> 
> diff --git a/xen/include/xen/refcnt.h b/xen/include/xen/refcnt.h
> new file mode 100644
> index 0000000000..1ac05d927c
> --- /dev/null
> +++ b/xen/include/xen/refcnt.h
> @@ -0,0 +1,59 @@

This seems to be missing some kind of license, can we have an SPDX tag
at least?

> +#ifndef __XEN_REFCNT_H__
> +#define __XEN_REFCNT_H__
> +
> +#include <asm/atomic.h>
> +#include <asm/bug.h>
> +
> +#define REFCNT_SATURATED (INT_MIN / 2)
> +
> +typedef struct {
> +    atomic_t refcnt;
> +} refcnt_t;
> +
> +static inline void refcnt_init(refcnt_t *refcnt)
> +{
> +    atomic_set(&refcnt->refcnt, 1);
> +}
> +
> +static inline int refcnt_read(refcnt_t *refcnt)

const.

> +{
> +    return atomic_read(&refcnt->refcnt);
> +}
> +
> +static inline void refcnt_get(refcnt_t *refcnt)
> +{
> +    int old = atomic_add_unless(&refcnt->refcnt, 1, 0);
> +
> +    if ( unlikely(old < 0) || unlikely (old + 1 < 0) )
                                         ^ extra space

You want a single unlikely for both conditions.

> +    {
> +        atomic_set(&refcnt->refcnt, REFCNT_SATURATED);
> +        printk(XENLOG_ERR"refcnt saturation: old = %d\n", old);

Should this be printed only once for refcount? I fear it might spam
the console once a refcnt hits it.

> +        WARN();
> +    }
> +}
> +
> +static inline void refcnt_put(refcnt_t *refcnt, void (*destructor)(refcnt_t 
> *refcnt))
> +{
> +    int ret = atomic_dec_return(&refcnt->refcnt);
> +
> +    if ( ret == 0 )
> +        destructor(refcnt);
> +
> +    if ( unlikely(ret < 0))
                            ^ missing space
> +    {
> +        atomic_set(&refcnt->refcnt, REFCNT_SATURATED);
> +        printk(XENLOG_ERR"refcnt already hit 0: val = %d\n", ret);

Same here regarding the spamming.

> +        WARN();
> +    }
> +}
> +

Extra newline.

I will look at further patches to see how this gets used.

Thanks, Roger.



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.