linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] lib/stackdepot: use a non-instrumented version of memcmp()
@ 2017-11-15 17:34 Alexander Potapenko
  2017-11-16 15:08 ` Andrey Ryabinin
  0 siblings, 1 reply; 3+ messages in thread
From: Alexander Potapenko @ 2017-11-15 17:34 UTC (permalink / raw)
  To: aryabinin, dvyukov, akpm; +Cc: kasan-dev, linux-kernel, linux-mm

stackdepot used to call memcmp(), which compiler tools normally
instrument, therefore every lookup used to unnecessarily call
instrumented code.
This is somewhat ok in the case of KASAN, but under KMSAN a lot of time
was spent in the instrumentation.

Signed-off-by: Alexander Potapenko <glider@google.com>
---
 lib/stackdepot.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/lib/stackdepot.c b/lib/stackdepot.c
index f87d138e9672..d372101e8dc2 100644
--- a/lib/stackdepot.c
+++ b/lib/stackdepot.c
@@ -163,6 +163,23 @@ static inline u32 hash_stack(unsigned long *entries, unsigned int size)
 			       STACK_HASH_SEED);
 }
 
+/* Use our own, non-instrumented version of memcmp().
+ *
+ * We actually don't care about the order, just the equality.
+ */
+static inline
+int stackdepot_memcmp(const void *s1, const void *s2, unsigned int n)
+{
+	unsigned long *u1 = (unsigned long *)s1;
+	unsigned long *u2 = (unsigned long *)s2;
+
+	for ( ; n-- ; u1++, u2++) {
+		if (*u1 != *u2)
+			return 1;
+	}
+	return 0;
+}
+
 /* Find a stack that is equal to the one stored in entries in the hash */
 static inline struct stack_record *find_stack(struct stack_record *bucket,
 					     unsigned long *entries, int size,
@@ -173,10 +190,8 @@ static inline struct stack_record *find_stack(struct stack_record *bucket,
 	for (found = bucket; found; found = found->next) {
 		if (found->hash == hash &&
 		    found->size == size &&
-		    !memcmp(entries, found->entries,
-			    size * sizeof(unsigned long))) {
+		    !stackdepot_memcmp(entries, found->entries, size))
 			return found;
-		}
 	}
 	return NULL;
 }
-- 
2.15.0.448.gf294e3d99a-goog

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

* Re: [PATCH] lib/stackdepot: use a non-instrumented version of memcmp()
  2017-11-15 17:34 [PATCH] lib/stackdepot: use a non-instrumented version of memcmp() Alexander Potapenko
@ 2017-11-16 15:08 ` Andrey Ryabinin
  2017-11-16 16:29   ` Alexander Potapenko
  0 siblings, 1 reply; 3+ messages in thread
From: Andrey Ryabinin @ 2017-11-16 15:08 UTC (permalink / raw)
  To: Alexander Potapenko, dvyukov, akpm; +Cc: kasan-dev, linux-kernel, linux-mm



On 11/15/2017 08:34 PM, Alexander Potapenko wrote:
> stackdepot used to call memcmp(), which compiler tools normally
> instrument, therefore every lookup used to unnecessarily call
> instrumented code.
> This is somewhat ok in the case of KASAN, but under KMSAN a lot of time
> was spent in the instrumentation.
> 
> Signed-off-by: Alexander Potapenko <glider@google.com>
> ---
>  lib/stackdepot.c | 21 ++++++++++++++++++---
>  1 file changed, 18 insertions(+), 3 deletions(-)
> 
> diff --git a/lib/stackdepot.c b/lib/stackdepot.c
> index f87d138e9672..d372101e8dc2 100644
> --- a/lib/stackdepot.c
> +++ b/lib/stackdepot.c
> @@ -163,6 +163,23 @@ static inline u32 hash_stack(unsigned long *entries, unsigned int size)
>  			       STACK_HASH_SEED);
>  }
>  
> +/* Use our own, non-instrumented version of memcmp().
> + *
> + * We actually don't care about the order, just the equality.
> + */
> +static inline
> +int stackdepot_memcmp(const void *s1, const void *s2, unsigned int n)
> +{

Why 'void *' types? The function treats s1, s2 as array of long, also 'n' is number of longs here.

> +	unsigned long *u1 = (unsigned long *)s1;
> +	unsigned long *u2 = (unsigned long *)s2;
> +
> +	for ( ; n-- ; u1++, u2++) {
> +		if (*u1 != *u2)
> +			return 1;
> +	}
> +	return 0;
> +}
> +
>  /* Find a stack that is equal to the one stored in entries in the hash */
>  static inline struct stack_record *find_stack(struct stack_record *bucket,
>  					     unsigned long *entries, int size,
> @@ -173,10 +190,8 @@ static inline struct stack_record *find_stack(struct stack_record *bucket,
>  	for (found = bucket; found; found = found->next) {
>  		if (found->hash == hash &&
>  		    found->size == size &&
> -		    !memcmp(entries, found->entries,
> -			    size * sizeof(unsigned long))) {
> +		    !stackdepot_memcmp(entries, found->entries, size))
>  			return found;
> -		}
>  	}
>  	return NULL;
>  }
> 

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

* Re: [PATCH] lib/stackdepot: use a non-instrumented version of memcmp()
  2017-11-16 15:08 ` Andrey Ryabinin
@ 2017-11-16 16:29   ` Alexander Potapenko
  0 siblings, 0 replies; 3+ messages in thread
From: Alexander Potapenko @ 2017-11-16 16:29 UTC (permalink / raw)
  To: Andrey Ryabinin
  Cc: Dmitriy Vyukov, Andrew Morton, kasan-dev, LKML,
	Linux Memory Management List

On Thu, Nov 16, 2017 at 4:08 PM, Andrey Ryabinin
<aryabinin@virtuozzo.com> wrote:
>
>
> On 11/15/2017 08:34 PM, Alexander Potapenko wrote:
>> stackdepot used to call memcmp(), which compiler tools normally
>> instrument, therefore every lookup used to unnecessarily call
>> instrumented code.
>> This is somewhat ok in the case of KASAN, but under KMSAN a lot of time
>> was spent in the instrumentation.
>>
>> Signed-off-by: Alexander Potapenko <glider@google.com>
>> ---
>>  lib/stackdepot.c | 21 ++++++++++++++++++---
>>  1 file changed, 18 insertions(+), 3 deletions(-)
>>
>> diff --git a/lib/stackdepot.c b/lib/stackdepot.c
>> index f87d138e9672..d372101e8dc2 100644
>> --- a/lib/stackdepot.c
>> +++ b/lib/stackdepot.c
>> @@ -163,6 +163,23 @@ static inline u32 hash_stack(unsigned long *entries, unsigned int size)
>>                              STACK_HASH_SEED);
>>  }
>>
>> +/* Use our own, non-instrumented version of memcmp().
>> + *
>> + * We actually don't care about the order, just the equality.
>> + */
>> +static inline
>> +int stackdepot_memcmp(const void *s1, const void *s2, unsigned int n)
>> +{
>
> Why 'void *' types? The function treats s1, s2 as array of long, also 'n' is number of longs here.
Agreed. I started with a plain memcpy, so the arg types were left over.
>> +     unsigned long *u1 = (unsigned long *)s1;
>> +     unsigned long *u2 = (unsigned long *)s2;
>> +
>> +     for ( ; n-- ; u1++, u2++) {
>> +             if (*u1 != *u2)
>> +                     return 1;
>> +     }
>> +     return 0;
>> +}
>> +
>>  /* Find a stack that is equal to the one stored in entries in the hash */
>>  static inline struct stack_record *find_stack(struct stack_record *bucket,
>>                                            unsigned long *entries, int size,
>> @@ -173,10 +190,8 @@ static inline struct stack_record *find_stack(struct stack_record *bucket,
>>       for (found = bucket; found; found = found->next) {
>>               if (found->hash == hash &&
>>                   found->size == size &&
>> -                 !memcmp(entries, found->entries,
>> -                         size * sizeof(unsigned long))) {
>> +                 !stackdepot_memcmp(entries, found->entries, size))
>>                       return found;
>> -             }
>>       }
>>       return NULL;
>>  }
>>



-- 
Alexander Potapenko
Software Engineer

Google Germany GmbH
Erika-Mann-Straße, 33
80636 München

Geschäftsführer: Paul Manicle, Halimah DeLaine Prado
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg

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

end of thread, other threads:[~2017-11-16 16:29 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-15 17:34 [PATCH] lib/stackdepot: use a non-instrumented version of memcmp() Alexander Potapenko
2017-11-16 15:08 ` Andrey Ryabinin
2017-11-16 16:29   ` Alexander Potapenko

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).