linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] Introduce kref_sub
@ 2010-11-16 14:21 Thomas Hellstrom
  2010-11-16 14:21 ` [PATCH 1/2] kref: Add a kref_sub function Thomas Hellstrom
  0 siblings, 1 reply; 3+ messages in thread
From: Thomas Hellstrom @ 2010-11-16 14:21 UTC (permalink / raw)
  To: airlied; +Cc: dri-devel, linux-kernel

Adding a function in order to be able to optimize away a number of locked
bus cycles. Callers might for whatever reason want to accumulate unreferences
in certain code paths (rcu grace periods, atomic regions ...). This makes
it possible to perform the batched unreference more efficiently.

If accepted, I'd prefer patch 1 goes through Dave's DRM tree.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] kref: Add a kref_sub function
  2010-11-16 14:21 [PATCH 0/2] Introduce kref_sub Thomas Hellstrom
@ 2010-11-16 14:21 ` Thomas Hellstrom
  2010-11-16 14:21   ` [PATCH 2/2] drm/ttm: Use kref_sub instead of repeatedly calling kref_put Thomas Hellstrom
  0 siblings, 1 reply; 3+ messages in thread
From: Thomas Hellstrom @ 2010-11-16 14:21 UTC (permalink / raw)
  To: airlied; +Cc: dri-devel, linux-kernel, Thomas Hellstrom

Makes it possible to optimize batched multiple unrefs.
Initial user will be drivers/gpu/ttm which accumulates unrefs to be
processed outside of atomic code.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
---
 include/linux/kref.h |    2 ++
 lib/kref.c           |   30 ++++++++++++++++++++++++++++++
 2 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/include/linux/kref.h b/include/linux/kref.h
index 6cc38fc..d4a62ab 100644
--- a/include/linux/kref.h
+++ b/include/linux/kref.h
@@ -24,5 +24,7 @@ struct kref {
 void kref_init(struct kref *kref);
 void kref_get(struct kref *kref);
 int kref_put(struct kref *kref, void (*release) (struct kref *kref));
+int kref_sub(struct kref *kref, unsigned int count,
+	     void (*release) (struct kref *kref));
 
 #endif /* _KREF_H_ */
diff --git a/lib/kref.c b/lib/kref.c
index d3d227a..3efb882 100644
--- a/lib/kref.c
+++ b/lib/kref.c
@@ -62,6 +62,36 @@ int kref_put(struct kref *kref, void (*release)(struct kref *kref))
 	return 0;
 }
 
+
+/**
+ * kref_sub - subtract a number of refcounts for object.
+ * @kref: object.
+ * @count: Number of recounts to subtract.
+ * @release: pointer to the function that will clean up the object when the
+ *	     last reference to the object is released.
+ *	     This pointer is required, and it is not acceptable to pass kfree
+ *	     in as this function.
+ *
+ * Subtract @count from the refcount, and if 0, call release().
+ * Return 1 if the object was removed, otherwise return 0.  Beware, if this
+ * function returns 0, you still can not count on the kref from remaining in
+ * memory.  Only use the return value if you want to see if the kref is now
+ * gone, not present.
+ */
+int kref_sub(struct kref *kref, unsigned int count,
+	     void (*release)(struct kref *kref))
+{
+	WARN_ON(release == NULL);
+	WARN_ON(release == (void (*)(struct kref *))kfree);
+
+	if (atomic_sub_and_test((int) count, &kref->refcount)) {
+		release(kref);
+		return 1;
+	}
+	return 0;
+}
+
 EXPORT_SYMBOL(kref_init);
 EXPORT_SYMBOL(kref_get);
 EXPORT_SYMBOL(kref_put);
+EXPORT_SYMBOL(kref_sub);
-- 
1.6.2.5


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] drm/ttm: Use kref_sub instead of repeatedly calling kref_put
  2010-11-16 14:21 ` [PATCH 1/2] kref: Add a kref_sub function Thomas Hellstrom
@ 2010-11-16 14:21   ` Thomas Hellstrom
  0 siblings, 0 replies; 3+ messages in thread
From: Thomas Hellstrom @ 2010-11-16 14:21 UTC (permalink / raw)
  To: airlied; +Cc: dri-devel, linux-kernel, Thomas Hellstrom

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
---
 drivers/gpu/drm/ttm/ttm_bo.c |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index a586378..9ef893d 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -266,10 +266,8 @@ static void ttm_bo_ref_bug(struct kref *list_kref)
 void ttm_bo_list_ref_sub(struct ttm_buffer_object *bo, int count,
 			 bool never_free)
 {
-	while (count--)
-		kref_put(&bo->list_kref,
-			 (never_free || (count >= 0)) ? ttm_bo_ref_bug :
-			 ttm_bo_release_list);
+	kref_sub(&bo->list_kref, count,
+		 (never_free) ? ttm_bo_ref_bug : ttm_bo_release_list);
 }
 
 int ttm_bo_reserve(struct ttm_buffer_object *bo,
-- 
1.6.2.5


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2010-11-16 14:21 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-16 14:21 [PATCH 0/2] Introduce kref_sub Thomas Hellstrom
2010-11-16 14:21 ` [PATCH 1/2] kref: Add a kref_sub function Thomas Hellstrom
2010-11-16 14:21   ` [PATCH 2/2] drm/ttm: Use kref_sub instead of repeatedly calling kref_put Thomas Hellstrom

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).