public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] remove redundant NULL pointer checks prior to calling kfree() in fs/nfsd/
@ 2005-03-25 22:22 Jesper Juhl
  2005-03-25 22:34 ` linux-os
  0 siblings, 1 reply; 7+ messages in thread
From: Jesper Juhl @ 2005-03-25 22:22 UTC (permalink / raw)
  To: Neil Brown; +Cc: nfs, Trond Myklebust, linux-kernel

(please keep me on CC)


checking for NULL before calling kfree() is redundant and needlessly 
enlarges the kernel image, let's get rid of those checks.

Signed-off-by: Jesper Juhl <juhl-lkml@dif.dk>

--- linux-2.6.12-rc1-mm3-orig/fs/nfsd/export.c	2005-03-21 23:12:41.000000000 +0100
+++ linux-2.6.12-rc1-mm3/fs/nfsd/export.c	2005-03-25 22:48:11.000000000 +0100
@@ -189,8 +189,7 @@ static int expkey_parse(struct cache_det
  out:
 	if (dom)
 		auth_domain_put(dom);
-	if (buf)
-		kfree(buf);
+	kfree(buf);
 	return err;
 }
 
@@ -426,8 +425,7 @@ static int svc_export_parse(struct cache
 		path_release(&nd);
 	if (dom)
 		auth_domain_put(dom);
-	if (buf)
-		kfree(buf);
+	kfree(buf);
 	return err;
 }
 
--- linux-2.6.12-rc1-mm3-orig/fs/nfsd/nfs4xdr.c	2005-03-25 15:28:59.000000000 +0100
+++ linux-2.6.12-rc1-mm3/fs/nfsd/nfs4xdr.c	2005-03-25 22:49:53.000000000 +0100
@@ -151,8 +151,7 @@ u32 *read_buf(struct nfsd4_compoundargs 
 	if (nbytes <= sizeof(argp->tmp))
 		p = argp->tmp;
 	else {
-		if (argp->tmpp)
-			kfree(argp->tmpp);
+		kfree(argp->tmpp);
 		p = argp->tmpp = kmalloc(nbytes, GFP_KERNEL);
 		if (!p)
 			return NULL;
@@ -2474,10 +2473,8 @@ void nfsd4_release_compoundargs(struct n
 		kfree(args->ops);
 		args->ops = args->iops;
 	}
-	if (args->tmpp) {
-		kfree(args->tmpp);
-		args->tmpp = NULL;
-	}
+	kfree(args->tmpp);
+	args->tmpp = NULL;
 	while (args->to_free) {
 		struct tmpbuf *tb = args->to_free;
 		args->to_free = tb->next;
--- linux-2.6.12-rc1-mm3-orig/fs/nfsd/nfscache.c	2005-03-21 23:12:41.000000000 +0100
+++ linux-2.6.12-rc1-mm3/fs/nfsd/nfscache.c	2005-03-25 22:50:14.000000000 +0100
@@ -93,8 +93,7 @@ nfsd_cache_shutdown(void)
 
 	cache_disabled = 1;
 
-	if (hash_list)
-		kfree (hash_list);
+	kfree(hash_list);
 	hash_list = NULL;
 }
 



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

* Re: [PATCH] remove redundant NULL pointer checks prior to calling kfree() in fs/nfsd/
  2005-03-25 22:22 [PATCH] remove redundant NULL pointer checks prior to calling kfree() in fs/nfsd/ Jesper Juhl
@ 2005-03-25 22:34 ` linux-os
  2005-03-25 23:12   ` Jesper Juhl
                     ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: linux-os @ 2005-03-25 22:34 UTC (permalink / raw)
  To: Jesper Juhl; +Cc: Neil Brown, nfs, Trond Myklebust, linux-kernel

On Fri, 25 Mar 2005, Jesper Juhl wrote:

> (please keep me on CC)
>
>
> checking for NULL before calling kfree() is redundant and needlessly
> enlarges the kernel image, let's get rid of those checks.
>

Hardly. ORing a value with itself and jumping on condition is
real cheap compared with pushing a value into the stack and
calling a function. This is NOT a good change if you want
performance. You really should reconsider this activity. It
is quite counter-productive.


> Signed-off-by: Jesper Juhl <juhl-lkml@dif.dk>
>
> --- linux-2.6.12-rc1-mm3-orig/fs/nfsd/export.c	2005-03-21 23:12:41.000000000 +0100
> +++ linux-2.6.12-rc1-mm3/fs/nfsd/export.c	2005-03-25 22:48:11.000000000 +0100
> @@ -189,8 +189,7 @@ static int expkey_parse(struct cache_det
>  out:
> 	if (dom)
> 		auth_domain_put(dom);
> -	if (buf)
> -		kfree(buf);
> +	kfree(buf);
> 	return err;
> }
>
> @@ -426,8 +425,7 @@ static int svc_export_parse(struct cache
> 		path_release(&nd);
> 	if (dom)
> 		auth_domain_put(dom);
> -	if (buf)
> -		kfree(buf);
> +	kfree(buf);
> 	return err;
> }
>
> --- linux-2.6.12-rc1-mm3-orig/fs/nfsd/nfs4xdr.c	2005-03-25 15:28:59.000000000 +0100
> +++ linux-2.6.12-rc1-mm3/fs/nfsd/nfs4xdr.c	2005-03-25 22:49:53.000000000 +0100
> @@ -151,8 +151,7 @@ u32 *read_buf(struct nfsd4_compoundargs
> 	if (nbytes <= sizeof(argp->tmp))
> 		p = argp->tmp;
> 	else {
> -		if (argp->tmpp)
> -			kfree(argp->tmpp);
> +		kfree(argp->tmpp);
> 		p = argp->tmpp = kmalloc(nbytes, GFP_KERNEL);
> 		if (!p)
> 			return NULL;
> @@ -2474,10 +2473,8 @@ void nfsd4_release_compoundargs(struct n
> 		kfree(args->ops);
> 		args->ops = args->iops;
> 	}
> -	if (args->tmpp) {
> -		kfree(args->tmpp);
> -		args->tmpp = NULL;
> -	}
> +	kfree(args->tmpp);
> +	args->tmpp = NULL;
> 	while (args->to_free) {
> 		struct tmpbuf *tb = args->to_free;
> 		args->to_free = tb->next;
> --- linux-2.6.12-rc1-mm3-orig/fs/nfsd/nfscache.c	2005-03-21 23:12:41.000000000 +0100
> +++ linux-2.6.12-rc1-mm3/fs/nfsd/nfscache.c	2005-03-25 22:50:14.000000000 +0100
> @@ -93,8 +93,7 @@ nfsd_cache_shutdown(void)
>
> 	cache_disabled = 1;
>
> -	if (hash_list)
> -		kfree (hash_list);
> +	kfree(hash_list);
> 	hash_list = NULL;
> }
>
>
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>

Cheers,
Dick Johnson
Penguin : Linux version 2.6.11 on an i686 machine (5537.79 BogoMips).
  Notice : All mail here is now cached for review by Dictator Bush.
                  98.36% of all statistics are fiction.

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

* Re: [PATCH] remove redundant NULL pointer checks prior to calling kfree() in fs/nfsd/
  2005-03-25 22:34 ` linux-os
@ 2005-03-25 23:12   ` Jesper Juhl
  2005-03-26  8:34   ` Arjan van de Ven
  2005-03-27 14:00   ` Pekka Enberg
  2 siblings, 0 replies; 7+ messages in thread
From: Jesper Juhl @ 2005-03-25 23:12 UTC (permalink / raw)
  To: linux-os; +Cc: Jesper Juhl, Neil Brown, nfs, Trond Myklebust, linux-kernel

On Fri, 25 Mar 2005, linux-os wrote:

> On Fri, 25 Mar 2005, Jesper Juhl wrote:
> 
> > (please keep me on CC)
> > 
> > 
> > checking for NULL before calling kfree() is redundant and needlessly
> > enlarges the kernel image, let's get rid of those checks.
> > 
> 
> Hardly. ORing a value with itself and jumping on condition is
> real cheap compared with pushing a value into the stack and
> calling a function. This is NOT a good change if you want
> performance. You really should reconsider this activity. It
> is quite counter-productive.
> 
> 
Let's have a look - at fs/nfsd/export.o for example.

Size first.
Without my patch :
$ ls -l fs/nfsd/export.o
-rw-r--r--  1 juhl users 97144 2005-03-25 23:58 fs/nfsd/export.o
With my patch : 
$ ls -l fs/nfsd/export.o
-rw-r--r--  1 juhl users 97092 2005-03-25 23:59 fs/nfsd/export.o

That's our first bennefit - 52 bytes saved - not much, but still some.


Now let's take a look at the code gcc generates for one of the functions - 
expkey_parse for example. Here's a diff -u of an  objdump -D  of export.o 
cut down to just the bit for expkey_parse : 

--- func-without-patch	2005-03-26 00:02:47.000000000 +0100
+++ func-with-patch	2005-03-26 00:03:26.000000000 +0100
@@ -8,7 +8,7 @@
      13b:	81 ec d0 00 00 00    	sub    $0xd0,%esp
      141:	89 95 40 ff ff ff    	mov    %edx,0xffffff40(%ebp)
      147:	80 7c 0a ff 0a       	cmpb   $0xa,0xffffffff(%edx,%ecx,1)
-     14c:	0f 85 2b 02 00 00    	jne    37d <expkey_parse+0x24d>
+     14c:	0f 85 27 02 00 00    	jne    379 <expkey_parse+0x249>
      152:	c6 44 0a ff 00       	movb   $0x0,0xffffffff(%edx,%ecx,1)
      157:	a1 64 00 00 00       	mov    0x64,%eax
      15c:	ba d0 00 00 00       	mov    $0xd0,%edx
@@ -17,7 +17,7 @@
      168:	89 c3                	mov    %eax,%ebx
      16a:	c7 85 30 ff ff ff f4 	movl   $0xfffffff4,0xffffff30(%ebp)
      171:	ff ff ff 
-     174:	0f 84 fd 01 00 00    	je     377 <expkey_parse+0x247>
+     174:	0f 84 f2 01 00 00    	je     36c <expkey_parse+0x23c>
      17a:	89 c2                	mov    %eax,%edx
      17c:	8d 85 40 ff ff ff    	lea    0xffffff40(%ebp),%eax
      182:	b9 00 10 00 00       	mov    $0x1000,%ecx
@@ -52,7 +52,7 @@
      208:	80 38 00             	cmpb   $0x0,(%eax)
      20b:	0f 85 46 01 00 00    	jne    357 <expkey_parse+0x227>
      211:	f6 05 00 00 00 00 04 	testb  $0x4,0x0
-     218:	0f 85 6a 01 00 00    	jne    388 <expkey_parse+0x258>
+     218:	0f 85 66 01 00 00    	jne    384 <expkey_parse+0x254>
      21e:	83 ff 02             	cmp    $0x2,%edi
      221:	0f 8f 30 01 00 00    	jg     357 <expkey_parse+0x227>
      227:	8d 85 40 ff ff ff    	lea    0xffffff40(%ebp),%eax
@@ -134,22 +134,20 @@
      35f:	74 0b                	je     36c <expkey_parse+0x23c>
      361:	8b 85 34 ff ff ff    	mov    0xffffff34(%ebp),%eax
      367:	e8 fc ff ff ff       	call   368 <expkey_parse+0x238>
-     36c:	85 db                	test   %ebx,%ebx
-     36e:	74 07                	je     377 <expkey_parse+0x247>
-     370:	89 d8                	mov    %ebx,%eax
-     372:	e8 fc ff ff ff       	call   373 <expkey_parse+0x243>
-     377:	8b 85 30 ff ff ff    	mov    0xffffff30(%ebp),%eax
-     37d:	81 c4 d0 00 00 00    	add    $0xd0,%esp
-     383:	5b                   	pop    %ebx
-     384:	5e                   	pop    %esi
-     385:	5f                   	pop    %edi
-     386:	c9                   	leave  
-     387:	c3                   	ret    
-     388:	89 7c 24 04          	mov    %edi,0x4(%esp)
-     38c:	c7 04 24 03 00 00 00 	movl   $0x3,(%esp)
-     393:	e8 fc ff ff ff       	call   394 <expkey_parse+0x264>
-     398:	e9 81 fe ff ff       	jmp    21e <expkey_parse+0xee>
-     39d:	8d 76 00             	lea    0x0(%esi),%esi
+     36c:	89 d8                	mov    %ebx,%eax
+     36e:	e8 fc ff ff ff       	call   36f <expkey_parse+0x23f>
+     373:	8b 85 30 ff ff ff    	mov    0xffffff30(%ebp),%eax
+     379:	81 c4 d0 00 00 00    	add    $0xd0,%esp
+     37f:	5b                   	pop    %ebx
+     380:	5e                   	pop    %esi
+     381:	5f                   	pop    %edi
+     382:	c9                   	leave  
+     383:	c3                   	ret    
+     384:	89 7c 24 04          	mov    %edi,0x4(%esp)
+     388:	c7 04 24 03 00 00 00 	movl   $0x3,(%esp)
+     38f:	e8 fc ff ff ff       	call   390 <expkey_parse+0x260>
+     394:	e9 85 fe ff ff       	jmp    21e <expkey_parse+0xee>
+     399:	8d b4 26 00 00 00 00 	lea    0x0(%esi),%esi
      3a0:	89 5c 24 04          	mov    %ebx,0x4(%esp)
      3a4:	c7 04 24 16 00 00 00 	movl   $0x16,(%esp)
      3ab:	e8 fc ff ff ff       	call   3ac <expkey_parse+0x27c>

This is not too bad, but I've seen a lot worse, see this one for a gross 
example : http://www.ussg.iu.edu/hypermail/linux/kernel/0503.2/1050.html


-- 
Jesper Juhl
 

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

* Re: [PATCH] remove redundant NULL pointer checks prior to calling kfree() in fs/nfsd/
  2005-03-25 22:34 ` linux-os
  2005-03-25 23:12   ` Jesper Juhl
@ 2005-03-26  8:34   ` Arjan van de Ven
  2005-03-27 12:45     ` Denis Vlasenko
  2005-03-27 14:00   ` Pekka Enberg
  2 siblings, 1 reply; 7+ messages in thread
From: Arjan van de Ven @ 2005-03-26  8:34 UTC (permalink / raw)
  To: linux-os; +Cc: Jesper Juhl, Neil Brown, nfs, Trond Myklebust, linux-kernel

On Fri, 2005-03-25 at 17:34 -0500, linux-os wrote:
> On Fri, 25 Mar 2005, Jesper Juhl wrote:
> 
> > (please keep me on CC)
> >
> >
> > checking for NULL before calling kfree() is redundant and needlessly
> > enlarges the kernel image, let's get rid of those checks.
> >
> 
> Hardly. ORing a value with itself and jumping on condition is
> real cheap compared with pushing a value into the stack

which century are you from?
"jumping on condition" can easily be 100+ cycles, depending on how
effective the branch predictor is. Pushing a value onto the stack otoh
is half a cycle. 

Your argument was right probably in 1994, when cpus didn't do
speculation and out of order execution...



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

* Re: [PATCH] remove redundant NULL pointer checks prior to calling kfree() in fs/nfsd/
  2005-03-26  8:34   ` Arjan van de Ven
@ 2005-03-27 12:45     ` Denis Vlasenko
  2005-03-27 14:30       ` Arjan van de Ven
  0 siblings, 1 reply; 7+ messages in thread
From: Denis Vlasenko @ 2005-03-27 12:45 UTC (permalink / raw)
  To: Arjan van de Ven, linux-os
  Cc: Jesper Juhl, Neil Brown, nfs, Trond Myklebust, linux-kernel

On Saturday 26 March 2005 10:34, Arjan van de Ven wrote:
> On Fri, 2005-03-25 at 17:34 -0500, linux-os wrote:
> > On Fri, 25 Mar 2005, Jesper Juhl wrote:
> > 
> > > (please keep me on CC)
> > >
> > >
> > > checking for NULL before calling kfree() is redundant and needlessly
> > > enlarges the kernel image, let's get rid of those checks.
> > >
> > 
> > Hardly. ORing a value with itself and jumping on condition is
> > real cheap compared with pushing a value into the stack
> 
> which century are you from?
> "jumping on condition" can easily be 100+ cycles, depending on how
> effective the branch predictor is. Pushing a value onto the stack otoh
> is half a cycle.

linux-os is right because kfree does NULL check with exactly
the same code sequence, test and branch:

# objdump -d mm/slab.o
...
000012ef <kfree>:
    12ef:       55                      push   %ebp
    12f0:       89 e5                   mov    %esp,%ebp
    12f2:       57                      push   %edi
    12f3:       56                      push   %esi
    12f4:       53                      push   %ebx
    12f5:       51                      push   %ecx
    12f6:       8b 7d 08                mov    0x8(%ebp),%edi
    12f9:       85 ff                   test   %edi,%edi
    12fb:       74 46                   je     1343 <kfree+0x54>
...
...
...
    1343:       8d 65 f4                lea    0xfffffff4(%ebp),%esp
    1346:       5b                      pop    %ebx
    1347:       5e                      pop    %esi
    1348:       5f                      pop    %edi
    1349:       5d                      pop    %ebp
    134a:       c3                      ret

So kfree(p) indeed will spend time for doing a call,
for test-and-branch, *and* finally for ret,
while if(p) kfree(p) will do test-and-branch first
and won't do call/ret if p==NULL.

However, if p is not NULL, if(p) kfree(p) does:
1) test-and-branch (not taken)
2) call
3) another test-and-branch (not taken)!

I conclude that if(p) kfree(p) makes sense only if:
a) p is more often NULL than not, and
b) it's in the hot path (you don't want to save on code size)

Since (a) is not typical, I think Jesper's cleanups are ok.
--
vda


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

* Re: [PATCH] remove redundant NULL pointer checks prior to calling kfree() in fs/nfsd/
  2005-03-25 22:34 ` linux-os
  2005-03-25 23:12   ` Jesper Juhl
  2005-03-26  8:34   ` Arjan van de Ven
@ 2005-03-27 14:00   ` Pekka Enberg
  2 siblings, 0 replies; 7+ messages in thread
From: Pekka Enberg @ 2005-03-27 14:00 UTC (permalink / raw)
  To: linux-os
  Cc: Jesper Juhl, Neil Brown, nfs, Trond Myklebust, linux-kernel,
	penberg

On Fri, 25 Mar 2005 17:34:29 -0500 (EST), linux-os
<linux-os@analogic.com> wrote:
> You really should reconsider this activity. It is quite counter-productive.

No it's not. NULL is checked twice without Jesper's cleanups. If
kfree() calls are really that performance sensitive, just make it
inline and GCC will take care of it.

                                        Pekka

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

* Re: [PATCH] remove redundant NULL pointer checks prior to calling kfree() in fs/nfsd/
  2005-03-27 12:45     ` Denis Vlasenko
@ 2005-03-27 14:30       ` Arjan van de Ven
  0 siblings, 0 replies; 7+ messages in thread
From: Arjan van de Ven @ 2005-03-27 14:30 UTC (permalink / raw)
  To: Denis Vlasenko
  Cc: linux-os, Jesper Juhl, Neil Brown, nfs, Trond Myklebust,
	linux-kernel

On Sun, 2005-03-27 at 15:45 +0300, Denis Vlasenko wrote:
> On Saturday 26 March 2005 10:34, Arjan van de Ven wrote:
> > On Fri, 2005-03-25 at 17:34 -0500, linux-os wrote:
> > > On Fri, 25 Mar 2005, Jesper Juhl wrote:
> > > 
> > > > (please keep me on CC)
> > > >
> > > >
> > > > checking for NULL before calling kfree() is redundant and needlessly
> > > > enlarges the kernel image, let's get rid of those checks.
> > > >
> > > 
> > > Hardly. ORing a value with itself and jumping on condition is
> > > real cheap compared with pushing a value into the stack
> > 
> > which century are you from?
> > "jumping on condition" can easily be 100+ cycles, depending on how
> > effective the branch predictor is. Pushing a value onto the stack otoh
> > is half a cycle.
> 
> linux-os is right because kfree does NULL check with exactly
> the same code sequence, test and branch:

I know it does. The thing is that you have *two* chances to get a branch
mispredict now.

Now if kfree did NOT do the if but move it always to the caller, then
you have somewhat different dynamics (since you then always if the
conditional jump once no matter) but that is not the case.

> I conclude that if(p) kfree(p) makes sense only if:
> a) p is more often NULL than not, and
> b) it's in the hot path (you don't want to save on code size)
> 
> Since (a) is not typical, I think Jesper's cleanups are ok.

note that to gain from teh branch predictor "more often than not"
probably needs to be in the 20:1 ratio to actually gain.



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

end of thread, other threads:[~2005-03-27 14:30 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-25 22:22 [PATCH] remove redundant NULL pointer checks prior to calling kfree() in fs/nfsd/ Jesper Juhl
2005-03-25 22:34 ` linux-os
2005-03-25 23:12   ` Jesper Juhl
2005-03-26  8:34   ` Arjan van de Ven
2005-03-27 12:45     ` Denis Vlasenko
2005-03-27 14:30       ` Arjan van de Ven
2005-03-27 14:00   ` Pekka Enberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox