forked from mirrors/linux
		
	kunit: string-stream: Decouple string_stream from kunit
Re-work string_stream so that it is not tied to a struct kunit. This is
to allow using it for the log of struct kunit_suite.
Instead of resource-managing individual allocations the whole string_stream
can be resource-managed, if required.
    alloc_string_stream() now allocates a string stream that is
    not resource-managed.
    string_stream_destroy() now works on an unmanaged string_stream
    allocated by alloc_string_stream() and frees the entire
    string_stream (previously it only freed the fragments).
    string_stream_clear() has been made public for callers that
    want to free the fragments without destroying the string_stream.
For resource-managed allocations use kunit_alloc_string_stream()
and kunit_free_string_stream().
In addition to this, string_stream_get_string() now returns an
unmanaged buffer that the caller must kfree().
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
			
			
This commit is contained in:
		
							parent
							
								
									20631e154c
								
							
						
					
					
						commit
						a3fdf78478
					
				
					 4 changed files with 53 additions and 24 deletions
				
			
		|  | @ -11,11 +11,18 @@ | |||
| 
 | ||||
| #include "string-stream.h" | ||||
| 
 | ||||
| /* This avoids a cast warning if kfree() is passed direct to kunit_add_action(). */ | ||||
| static void kfree_wrapper(void *p) | ||||
| { | ||||
| 	kfree(p); | ||||
| } | ||||
| 
 | ||||
| static char *get_concatenated_string(struct kunit *test, struct string_stream *stream) | ||||
| { | ||||
| 	char *str = string_stream_get_string(stream); | ||||
| 
 | ||||
| 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, str); | ||||
| 	kunit_add_action(test, kfree_wrapper, (void *)str); | ||||
| 
 | ||||
| 	return str; | ||||
| } | ||||
|  | @ -30,7 +37,6 @@ static void string_stream_init_test(struct kunit *test) | |||
| 
 | ||||
| 	KUNIT_EXPECT_EQ(test, stream->length, 0); | ||||
| 	KUNIT_EXPECT_TRUE(test, list_empty(&stream->fragments)); | ||||
| 	KUNIT_EXPECT_PTR_EQ(test, stream->test, test); | ||||
| 	KUNIT_EXPECT_TRUE(test, (stream->gfp == GFP_KERNEL)); | ||||
| 	KUNIT_EXPECT_FALSE(test, stream->append_newlines); | ||||
| 	KUNIT_EXPECT_TRUE(test, string_stream_is_empty(stream)); | ||||
|  |  | |||
|  | @ -13,30 +13,28 @@ | |||
| #include "string-stream.h" | ||||
| 
 | ||||
| 
 | ||||
| static struct string_stream_fragment *alloc_string_stream_fragment( | ||||
| 		struct kunit *test, int len, gfp_t gfp) | ||||
| static struct string_stream_fragment *alloc_string_stream_fragment(int len, gfp_t gfp) | ||||
| { | ||||
| 	struct string_stream_fragment *frag; | ||||
| 
 | ||||
| 	frag = kunit_kzalloc(test, sizeof(*frag), gfp); | ||||
| 	frag = kzalloc(sizeof(*frag), gfp); | ||||
| 	if (!frag) | ||||
| 		return ERR_PTR(-ENOMEM); | ||||
| 
 | ||||
| 	frag->fragment = kunit_kmalloc(test, len, gfp); | ||||
| 	frag->fragment = kmalloc(len, gfp); | ||||
| 	if (!frag->fragment) { | ||||
| 		kunit_kfree(test, frag); | ||||
| 		kfree(frag); | ||||
| 		return ERR_PTR(-ENOMEM); | ||||
| 	} | ||||
| 
 | ||||
| 	return frag; | ||||
| } | ||||
| 
 | ||||
| static void string_stream_fragment_destroy(struct kunit *test, | ||||
| 					   struct string_stream_fragment *frag) | ||||
| static void string_stream_fragment_destroy(struct string_stream_fragment *frag) | ||||
| { | ||||
| 	list_del(&frag->node); | ||||
| 	kunit_kfree(test, frag->fragment); | ||||
| 	kunit_kfree(test, frag); | ||||
| 	kfree(frag->fragment); | ||||
| 	kfree(frag); | ||||
| } | ||||
| 
 | ||||
| int string_stream_vadd(struct string_stream *stream, | ||||
|  | @ -65,9 +63,7 @@ int string_stream_vadd(struct string_stream *stream, | |||
| 	/* Need space for null byte. */ | ||||
| 	buf_len++; | ||||
| 
 | ||||
| 	frag_container = alloc_string_stream_fragment(stream->test, | ||||
| 						      buf_len, | ||||
| 						      stream->gfp); | ||||
| 	frag_container = alloc_string_stream_fragment(buf_len, stream->gfp); | ||||
| 	if (IS_ERR(frag_container)) | ||||
| 		return PTR_ERR(frag_container); | ||||
| 
 | ||||
|  | @ -102,7 +98,7 @@ int string_stream_add(struct string_stream *stream, const char *fmt, ...) | |||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| static void string_stream_clear(struct string_stream *stream) | ||||
| void string_stream_clear(struct string_stream *stream) | ||||
| { | ||||
| 	struct string_stream_fragment *frag_container, *frag_container_safe; | ||||
| 
 | ||||
|  | @ -111,7 +107,7 @@ static void string_stream_clear(struct string_stream *stream) | |||
| 				 frag_container_safe, | ||||
| 				 &stream->fragments, | ||||
| 				 node) { | ||||
| 		string_stream_fragment_destroy(stream->test, frag_container); | ||||
| 		string_stream_fragment_destroy(frag_container); | ||||
| 	} | ||||
| 	stream->length = 0; | ||||
| 	spin_unlock(&stream->lock); | ||||
|  | @ -123,7 +119,7 @@ char *string_stream_get_string(struct string_stream *stream) | |||
| 	size_t buf_len = stream->length + 1; /* +1 for null byte. */ | ||||
| 	char *buf; | ||||
| 
 | ||||
| 	buf = kunit_kzalloc(stream->test, buf_len, stream->gfp); | ||||
| 	buf = kzalloc(buf_len, stream->gfp); | ||||
| 	if (!buf) | ||||
| 		return NULL; | ||||
| 
 | ||||
|  | @ -139,13 +135,17 @@ int string_stream_append(struct string_stream *stream, | |||
| 			 struct string_stream *other) | ||||
| { | ||||
| 	const char *other_content; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	other_content = string_stream_get_string(other); | ||||
| 
 | ||||
| 	if (!other_content) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	return string_stream_add(stream, other_content); | ||||
| 	ret = string_stream_add(stream, other_content); | ||||
| 	kfree(other_content); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| bool string_stream_is_empty(struct string_stream *stream) | ||||
|  | @ -153,16 +153,15 @@ bool string_stream_is_empty(struct string_stream *stream) | |||
| 	return list_empty(&stream->fragments); | ||||
| } | ||||
| 
 | ||||
| static struct string_stream *alloc_string_stream(struct kunit *test, gfp_t gfp) | ||||
| struct string_stream *alloc_string_stream(gfp_t gfp) | ||||
| { | ||||
| 	struct string_stream *stream; | ||||
| 
 | ||||
| 	stream = kunit_kzalloc(test, sizeof(*stream), gfp); | ||||
| 	stream = kzalloc(sizeof(*stream), gfp); | ||||
| 	if (!stream) | ||||
| 		return ERR_PTR(-ENOMEM); | ||||
| 
 | ||||
| 	stream->gfp = gfp; | ||||
| 	stream->test = test; | ||||
| 	INIT_LIST_HEAD(&stream->fragments); | ||||
| 	spin_lock_init(&stream->lock); | ||||
| 
 | ||||
|  | @ -171,15 +170,35 @@ static struct string_stream *alloc_string_stream(struct kunit *test, gfp_t gfp) | |||
| 
 | ||||
| void string_stream_destroy(struct string_stream *stream) | ||||
| { | ||||
| 	if (!stream) | ||||
| 		return; | ||||
| 
 | ||||
| 	string_stream_clear(stream); | ||||
| 	kfree(stream); | ||||
| } | ||||
| 
 | ||||
| static void resource_free_string_stream(void *p) | ||||
| { | ||||
| 	struct string_stream *stream = p; | ||||
| 
 | ||||
| 	string_stream_destroy(stream); | ||||
| } | ||||
| 
 | ||||
| struct string_stream *kunit_alloc_string_stream(struct kunit *test, gfp_t gfp) | ||||
| { | ||||
| 	return alloc_string_stream(test, gfp); | ||||
| 	struct string_stream *stream; | ||||
| 
 | ||||
| 	stream = alloc_string_stream(gfp); | ||||
| 	if (IS_ERR(stream)) | ||||
| 		return stream; | ||||
| 
 | ||||
| 	if (kunit_add_action_or_reset(test, resource_free_string_stream, stream) != 0) | ||||
| 		return ERR_PTR(-ENOMEM); | ||||
| 
 | ||||
| 	return stream; | ||||
| } | ||||
| 
 | ||||
| void kunit_free_string_stream(struct kunit *test, struct string_stream *stream) | ||||
| { | ||||
| 	string_stream_destroy(stream); | ||||
| 	kunit_release_action(test, resource_free_string_stream, (void *)stream); | ||||
| } | ||||
|  |  | |||
|  | @ -23,7 +23,6 @@ struct string_stream { | |||
| 	struct list_head fragments; | ||||
| 	/* length and fragments are protected by this lock */ | ||||
| 	spinlock_t lock; | ||||
| 	struct kunit *test; | ||||
| 	gfp_t gfp; | ||||
| 	bool append_newlines; | ||||
| }; | ||||
|  | @ -33,6 +32,9 @@ struct kunit; | |||
| struct string_stream *kunit_alloc_string_stream(struct kunit *test, gfp_t gfp); | ||||
| void kunit_free_string_stream(struct kunit *test, struct string_stream *stream); | ||||
| 
 | ||||
| struct string_stream *alloc_string_stream(gfp_t gfp); | ||||
| void free_string_stream(struct string_stream *stream); | ||||
| 
 | ||||
| int __printf(2, 3) string_stream_add(struct string_stream *stream, | ||||
| 				     const char *fmt, ...); | ||||
| 
 | ||||
|  | @ -40,6 +42,8 @@ int __printf(2, 0) string_stream_vadd(struct string_stream *stream, | |||
| 				      const char *fmt, | ||||
| 				      va_list args); | ||||
| 
 | ||||
| void string_stream_clear(struct string_stream *stream); | ||||
| 
 | ||||
| char *string_stream_get_string(struct string_stream *stream); | ||||
| 
 | ||||
| int string_stream_append(struct string_stream *stream, | ||||
|  |  | |||
|  | @ -296,7 +296,7 @@ static void kunit_print_string_stream(struct kunit *test, | |||
| 		kunit_err(test, "\n"); | ||||
| 	} else { | ||||
| 		kunit_err(test, "%s", buf); | ||||
| 		kunit_kfree(test, buf); | ||||
| 		kfree(buf); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Richard Fitzgerald
						Richard Fitzgerald