[PATCH] Improve talloc performance

Jeremy Allison jra at samba.org
Sat Jun 18 00:12:12 UTC 2016


On Fri, Jun 17, 2016 at 09:50:27PM +1200, Andrew Bartlett wrote:
> Attached is a patch to improve talloc performance, by calling
> talloc_chunk_from_ptr() less often.  I'm impressed by how much can be
> gained!  
> 
> Please carefully review!

I'm going through this right now, but one thing
that has to be done is to split this into a set of smaller
changesets as the chunks are too large to carefully parse
mentally (at least for me). Too much change per patchset.

This needs to be micro-changes, one per function as talloc
is such a core library.

For example:

1). Add extra struct talloc_chunk **tc_ret parameter to
__talloc_with_prefix(). Fix callers __talloc() and _talloc_pool().

2). Add extra struct talloc_chunk **tc_ret parameter to
__talloc(). Fix callers _talloc_named_const(),
talloc_named(), talloc_init(), _talloc(), __talloc_strlendup()
and talloc_vasprintf().

etc. etc.

This allows the total change to be rippled up through
the call chain one function at a time, and also allows
git bisection on each simple change.

Parts 1 and 2 above attached as an example of the
way to do this.

I'm excited enough about the speed increase to finish
rewriting this, as it looks great work !

Thanks,

	Jeremy.
-------------- next part --------------
From 201399399a7d2a24e8ab4eded09001e0e64ef5d6 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 17 Jun 2016 16:58:34 -0700
Subject: [PATCH 1/2] Part 1

Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
---
 lib/talloc/talloc.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c
index 48d2033..c37c9c8 100644
--- a/lib/talloc/talloc.c
+++ b/lib/talloc/talloc.c
@@ -625,8 +625,10 @@ static inline struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent
 /*
    Allocate a bit of memory as a child of an existing pointer
 */
-static inline void *__talloc_with_prefix(const void *context, size_t size,
-					size_t prefix_len)
+static inline void *__talloc_with_prefix(const void *context,
+					size_t size,
+					size_t prefix_len,
+					struct talloc_chunk **tc_ret)
 {
 	struct talloc_chunk *tc = NULL;
 	struct talloc_memlimit *limit = NULL;
@@ -700,12 +702,14 @@ static inline void *__talloc_with_prefix(const void *context, size_t size,
 		tc->next = tc->prev = tc->parent = NULL;
 	}
 
+	*tc_ret = tc;
 	return TC_PTR_FROM_CHUNK(tc);
 }
 
 static inline void *__talloc(const void *context, size_t size)
 {
-	return __talloc_with_prefix(context, size, 0);
+	struct talloc_chunk *tc;
+	return __talloc_with_prefix(context, size, 0, &tc);
 }
 
 /*
@@ -718,13 +722,12 @@ static inline void *_talloc_pool(const void *context, size_t size)
 	struct talloc_pool_hdr *pool_hdr;
 	void *result;
 
-	result = __talloc_with_prefix(context, size, TP_HDR_SIZE);
+	result = __talloc_with_prefix(context, size, TP_HDR_SIZE, &tc);
 
 	if (unlikely(result == NULL)) {
 		return NULL;
 	}
 
-	tc = talloc_chunk_from_ptr(result);
 	pool_hdr = talloc_pool_from_chunk(tc);
 
 	tc->flags |= TALLOC_FLAG_POOL;
-- 
2.8.0.rc3.226.g39d4020


From b233dae409b3a2d978be22482ac9320cfd985596 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 17 Jun 2016 17:06:52 -0700
Subject: [PATCH 2/2] Part 2

Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
---
 lib/talloc/talloc.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c
index c37c9c8..398657d 100644
--- a/lib/talloc/talloc.c
+++ b/lib/talloc/talloc.c
@@ -706,10 +706,11 @@ static inline void *__talloc_with_prefix(const void *context,
 	return TC_PTR_FROM_CHUNK(tc);
 }
 
-static inline void *__talloc(const void *context, size_t size)
+static inline void *__talloc(const void *context,
+			size_t size,
+			struct talloc_chunk **tc)
 {
-	struct talloc_chunk *tc;
-	return __talloc_with_prefix(context, size, 0, &tc);
+	return __talloc_with_prefix(context, size, 0, tc);
 }
 
 /*
@@ -864,8 +865,9 @@ static inline void _talloc_set_name_const(const void *ptr, const char *name)
 static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
 {
 	void *ptr;
+	struct talloc_chunk *tc;
 
-	ptr = __talloc(context, size);
+	ptr = __talloc(context, size, &tc);
 	if (unlikely(ptr == NULL)) {
 		return NULL;
 	}
@@ -1398,8 +1400,9 @@ _PUBLIC_ void *talloc_named(const void *context, size_t size, const char *fmt, .
 	va_list ap;
 	void *ptr;
 	const char *name;
+	struct talloc_chunk *tc;
 
-	ptr = __talloc(context, size);
+	ptr = __talloc(context, size, &tc);
 	if (unlikely(ptr == NULL)) return NULL;
 
 	va_start(ap, fmt);
@@ -1493,8 +1496,9 @@ _PUBLIC_ void *talloc_init(const char *fmt, ...)
 	va_list ap;
 	void *ptr;
 	const char *name;
+	struct talloc_chunk *tc;
 
-	ptr = __talloc(NULL, 0);
+	ptr = __talloc(NULL, 0, &tc);
 	if (unlikely(ptr == NULL)) return NULL;
 
 	va_start(ap, fmt);
@@ -1588,7 +1592,8 @@ _PUBLIC_ void talloc_free_children(void *ptr)
 */
 _PUBLIC_ void *_talloc(const void *context, size_t size)
 {
-	return __talloc(context, size);
+	struct talloc_chunk *tc;
+	return __talloc(context, size, &tc);
 }
 
 /*
@@ -2298,8 +2303,9 @@ _PUBLIC_ void *_talloc_memdup(const void *t, const void *p, size_t size, const c
 static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
 {
 	char *ret;
+	struct talloc_chunk *tc;
 
-	ret = (char *)__talloc(t, len + 1);
+	ret = (char *)__talloc(t, len + 1, &tc);
 	if (unlikely(!ret)) return NULL;
 
 	memcpy(ret, p, len);
@@ -2436,6 +2442,7 @@ _PUBLIC_ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
 	int len;
 	char *ret;
 	va_list ap2;
+	struct talloc_chunk *tc;
 	char buf[1024];
 
 	/* this call looks strange, but it makes it work on older solaris boxes */
@@ -2446,7 +2453,7 @@ _PUBLIC_ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
 		return NULL;
 	}
 
-	ret = (char *)__talloc(t, len+1);
+	ret = (char *)__talloc(t, len+1, &tc);
 	if (unlikely(!ret)) return NULL;
 
 	if (len < sizeof(buf)) {
-- 
2.8.0.rc3.226.g39d4020



More information about the samba-technical mailing list