All of lore.kernel.org
 help / color / mirror / Atom feed
From: Joe Perches <joe@perches.com>
To: Alexey Dobriyan <adobriyan@gmail.com>
Cc: akpm@linux-foundation.org, linux-kernel@vger.kernel.org,
	linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH v3] proc: faster open/read/close with "permanent" files
Date: Sun, 23 Feb 2020 18:48:38 -0800	[thread overview]
Message-ID: <dc93d5299169a33e00fc35a4c5f29ea72764bce0.camel@perches.com> (raw)
In-Reply-To: <20200223113024.GA4941@avx2>

On Sun, 2020-02-23 at 14:30 +0300, Alexey Dobriyan wrote:
> On Sat, Feb 22, 2020 at 12:39:39PM -0800, Joe Perches wrote:
> > On Sat, 2020-02-22 at 23:15 +0300, Alexey Dobriyan wrote:
> > > Now that "struct proc_ops" exist we can start putting there stuff which
> > > could not fly with VFS "struct file_operations"...
> > > 
> > > Most of fs/proc/inode.c file is dedicated to make open/read/.../close reliable
> > > in the event of disappearing /proc entries which usually happens if module is
> > > getting removed. Files like /proc/cpuinfo which never disappear simply do not
> > > need such protection.
> > > 
> > > Save 2 atomic ops, 1 allocation, 1 free per open/read/close sequence for such
> > > "permanent" files.
> > > 
> > > Enable "permanent" flag for
> > > 
> > > 	/proc/cpuinfo
> > > 	/proc/kmsg
> > > 	/proc/modules
> > > 	/proc/slabinfo
> > > 	/proc/stat
> > > 	/proc/sysvipc/*
> > > 	/proc/swaps
> > > 
> > > More will come once I figure out foolproof way to prevent out module
> > > authors from marking their stuff "permanent" for performance reasons
> > > when it is not.
> > > 
> > > This should help with scalability: benchmark is "read /proc/cpuinfo R times
> > > by N threads scattered over the system".
> > 
> > Is this an actual expected use-case?
> 
> Yes.
> 
> > Is there some additional unnecessary memory consumption
> > in the unscaled systems?
> 
> No, it's the opposite. Less memory usage for everyone and noticeable
> performance improvement for contented case.
> 
> > >  static ssize_t proc_reg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
> > >  {
> > >  	struct proc_dir_entry *pde = PDE(file_inode(file));
> > >  	ssize_t rv = -EIO;
> > > -	if (use_pde(pde)) {
> > > -		typeof_member(struct proc_ops, proc_read) read;
> > >  
> > > -		read = pde->proc_ops->proc_read;
> > > -		if (read)
> > > -			rv = read(file, buf, count, ppos);
> > > +	if (pde_is_permanent(pde)) {
> > > +		return pde_read(pde, file, buf, count, ppos);
> > > +	} else if (use_pde(pde)) {
> > > +		rv = pde_read(pde, file, buf, count, ppos);
> > >  		unuse_pde(pde);
> > 
> > Perhaps all the function call duplication could be minimized
> > by using code without direct returns like:
> > 
> > 	rv = pde_read(pde, file, buf, count, pos);
> > 	if (!pde_is_permanent(pde))
> > 		unuse_pde(pde);
> > 
> > 	return rv;
> 
> Function call non-duplication is false goal.

Depends, copy/paste errors are common and object code
size generally increases.

> Surprisingly it makes code bigger:

Not so far as I can tell.  Are you sure?

> 	$ ./scripts/bloat-o-meter ../vmlinux-000 ../obj/vmlinux
> 	add/remove: 0/0 grow/shrink: 1/0 up/down: 10/0 (10)
> 	Function                                     old     new   delta
> 	proc_reg_read                                108     118     +10
> 
> and worse too: "rv" is carried on stack through "unuse_pde" call.

With gcc 9.2.1 x86-64 defconfig:

Changing just proc_reg_read to:

static ssize_t proc_reg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
	struct proc_dir_entry *pde = PDE(file_inode(file));
	ssize_t rv;

	rv = pde_read(pde, file, buf, count, ppos);
	if (use_pde(pde))
		unuse_pde(pde);

	return rv;
}

gives:

$ size fs/proc/inode.o*
   text	   data	    bss	    dec	    hex	filename
   5448	     28	      0	   5476	   1564	fs/proc/inode.o.suggested
   5526	     28	      0	   5554	   15b2	fs/proc/inode.o.alexey

$ objdump -d fs/proc/inode.o.suggested (grep for proc_reg_read)
0000000000000410 <proc_reg_read>:
 410:	41 54                	push   %r12
 412:	55                   	push   %rbp
 413:	48 8b 47 20          	mov    0x20(%rdi),%rax
 417:	48 8b 68 d0          	mov    -0x30(%rax),%rbp
 41b:	48 8b 45 30          	mov    0x30(%rbp),%rax
 41f:	48 8b 40 10          	mov    0x10(%rax),%rax
 423:	48 85 c0             	test   %rax,%rax
 426:	74 28                	je     450 <proc_reg_read+0x40>
 428:	e8 00 00 00 00       	callq  42d <proc_reg_read+0x1d>
 42d:	49 89 c4             	mov    %rax,%r12
 430:	8b 45 00             	mov    0x0(%rbp),%eax
 433:	85 c0                	test   %eax,%eax
 435:	78 12                	js     449 <proc_reg_read+0x39>
 437:	8d 50 01             	lea    0x1(%rax),%edx
 43a:	f0 0f b1 55 00       	lock cmpxchg %edx,0x0(%rbp)
 43f:	75 f2                	jne    433 <proc_reg_read+0x23>
 441:	48 89 ef             	mov    %rbp,%rdi
 444:	e8 e7 fc ff ff       	callq  130 <unuse_pde>
 449:	4c 89 e0             	mov    %r12,%rax
 44c:	5d                   	pop    %rbp
 44d:	41 5c                	pop    %r12
 44f:	c3                   	retq   
 450:	49 c7 c4 fb ff ff ff 	mov    $0xfffffffffffffffb,%r12
 457:	eb d7                	jmp    430 <proc_reg_read+0x20>
 459:	0f 1f 80 00 00 00 00 	nopl   0x0(%rax)

vs
 
$ objdump -d fs/proc/inode.o.alexey (grep for proc_reg_read)

00000000000006e0 <proc_reg_read>:
 6e0:	41 54                	push   %r12
 6e2:	55                   	push   %rbp
 6e3:	48 8b 47 20          	mov    0x20(%rdi),%rax
 6e7:	48 8b 68 d0          	mov    -0x30(%rax),%rbp
 6eb:	f6 85 aa 00 00 00 01 	testb  $0x1,0xaa(%rbp)
 6f2:	74 15                	je     709 <proc_reg_read+0x29>
 6f4:	48 8b 45 30          	mov    0x30(%rbp),%rax
 6f8:	48 8b 40 10          	mov    0x10(%rax),%rax
 6fc:	48 85 c0             	test   %rax,%rax
 6ff:	74 3f                	je     740 <proc_reg_read+0x60>
 701:	5d                   	pop    %rbp
 702:	41 5c                	pop    %r12
 704:	e9 00 00 00 00       	jmpq   709 <proc_reg_read+0x29>
 709:	8b 45 00             	mov    0x0(%rbp),%eax
 70c:	85 c0                	test   %eax,%eax
 70e:	78 30                	js     740 <proc_reg_read+0x60>
 710:	44 8d 40 01          	lea    0x1(%rax),%r8d
 714:	f0 44 0f b1 45 00    	lock cmpxchg %r8d,0x0(%rbp)
 71a:	75 f0                	jne    70c <proc_reg_read+0x2c>
 71c:	48 8b 45 30          	mov    0x30(%rbp),%rax
 720:	48 8b 40 10          	mov    0x10(%rax),%rax
 724:	48 85 c0             	test   %rax,%rax
 727:	74 20                	je     749 <proc_reg_read+0x69>
 729:	e8 00 00 00 00       	callq  72e <proc_reg_read+0x4e>
 72e:	49 89 c4             	mov    %rax,%r12
 731:	48 89 ef             	mov    %rbp,%rdi
 734:	e8 f7 f9 ff ff       	callq  130 <unuse_pde>
 739:	4c 89 e0             	mov    %r12,%rax
 73c:	5d                   	pop    %rbp
 73d:	41 5c                	pop    %r12
 73f:	c3                   	retq   
 740:	49 c7 c4 fb ff ff ff 	mov    $0xfffffffffffffffb,%r12
 747:	eb f0                	jmp    739 <proc_reg_read+0x59>
 749:	49 c7 c4 fb ff ff ff 	mov    $0xfffffffffffffffb,%r12
 750:	eb df                	jmp    731 <proc_reg_read+0x51>
 752:	66 66 2e 0f 1f 84 00 	data16 nopw %cs:0x0(%rax,%rax,1)
 759:	00 00 00 00 
 75d:	0f 1f 00             	nopl   (%rax)



  reply	other threads:[~2020-02-24  2:50 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-22 20:15 [PATCH v3] proc: faster open/read/close with "permanent" files Alexey Dobriyan
2020-02-22 20:39 ` Joe Perches
2020-02-23 11:30   ` Alexey Dobriyan
2020-02-24  2:48     ` Joe Perches [this message]
2020-02-24 17:55       ` Alexey Dobriyan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=dc93d5299169a33e00fc35a4c5f29ea72764bce0.camel@perches.com \
    --to=joe@perches.com \
    --cc=adobriyan@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.