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

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


  • To: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Date: Tue, 14 Mar 2023 20:56:29 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=epam.com; dmarc=pass action=none header.from=epam.com; dkim=pass header.d=epam.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=x7tBqA5OxDzYHo/yEP4dPIJSk0WzvlCUdOtG1wDrd3k=; b=ZDVRNx9HfV+K8gSoeggq42pNM5AnOZyktEKjGKd8DEL0wyB1wNjMPBZM79GQrmNnQ9TQxZ/9dtHNjLE//E8IYPPL54TJwBWo9Nhz4MgypPxMpEbRBKARjUUML2lFV51NPUZWdecn01+RFzMF1IoPW71irrJTPLzoUpBE8G+ioDkGfWDRUqUJKv5ANPRcfTYbfZacGRMmMbDZHN1Srgm2YeJLZOjpL33bKyAndufK3Lf5RwaJ7CtdiXtf+DlBTfVvSHdCvgJyFIptyTLoECrUUA9KtbYTlY4rNQXyLAcibqWb8zG9sNxdWR1UdFl/FEmLgZ2J5v51mDLhoaOMZEi9ug==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=lWePQK1s5qlonxJcwc17I5daPq2zcSJZH51nt3y3H71wY6gfOKLq7tv4+alx8YCU9eRVukXzgUfWlrteom+Z5z9rAoXjLU/PbrukZnE4wn9mlbavwNA5wOCe2uZQpWZ9yS8k6dTehGDe/mSGXmU85Xrf5V5hgou8Y99SedG1HXBbYnK0z40lwNfjeJo6QKguVUgtLAk6XxdiYNYHf8tz5xNcIvIy8qgHUl6FwQqmQ0ETO4LZmIXosY54SqYfSyk2QQg12UKMV8wQH++WrS4CydO60JynRW5LhBKCJWP6qoMbcf3xfT8D4xwpm7uNMxCu5OCEOKrdCIBMuPlrQoXAxQ==
  • Cc: Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>, 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: Tue, 14 Mar 2023 20:57:12 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHZVrdyBx9pogLqRUq3RbhGdjZNSA==
  • Thread-topic: [PATCH v3 1/6] xen: add reference counter support

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.

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 @@
+#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)
+{
+    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) )
+    {
+        atomic_set(&refcnt->refcnt, REFCNT_SATURATED);
+        printk(XENLOG_ERR"refcnt saturation: old = %d\n", old);
+        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))
+    {
+        atomic_set(&refcnt->refcnt, REFCNT_SATURATED);
+        printk(XENLOG_ERR"refcnt already hit 0: val = %d\n", ret);
+        WARN();
+    }
+}
+
+#endif
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.39.2



 


Rackspace

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