pipe: reduce atime precision

The routine is called on successful write and read, which on pipes happens a
lot and for small sizes.

Precision provided by default seems way bigger than necessary and it causes
problems in vms on amd64 (it rdtscp's which vmexits). getnanotime seems to
provide the level roughly in lines of Linux so we should be good here.

Sample result from will-it-scale pipe1_processes -t 1 (ops/s):
before: 426464
after: 3247421

Note the that atime handling for named pipes is broken with and without the
patch. The filesystem code is never used for updating atime and never looks
at the updated field. Consequently, while there are no provisions added to
handle named pipes separately, the change is a nop for that case.

Differential Revision:	 https://reviews.freebsd.org/D23964
This commit is contained in:
Mateusz Guzik 2020-08-05 19:15:59 +00:00
parent c4cd699010
commit 4f00177887

View File

@ -230,6 +230,7 @@ static int pipe_create(struct pipe *pipe, bool backing);
static int pipe_paircreate(struct thread *td, struct pipepair **p_pp);
static __inline int pipelock(struct pipe *cpipe, int catch);
static __inline void pipeunlock(struct pipe *cpipe);
static void pipe_timestamp(struct timespec *tsp);
#ifndef PIPE_NODIRECT
static int pipe_build_write_buffer(struct pipe *wpipe, struct uio *uio);
static void pipe_destroy_write_buffer(struct pipe *wpipe);
@ -279,7 +280,7 @@ pipe_zone_ctor(void *mem, int size, void *arg, int flags)
*/
rpipe = &pp->pp_rpipe;
bzero(rpipe, sizeof(*rpipe));
vfs_timestamp(&rpipe->pipe_ctime);
pipe_timestamp(&rpipe->pipe_ctime);
rpipe->pipe_atime = rpipe->pipe_mtime = rpipe->pipe_ctime;
wpipe = &pp->pp_wpipe;
@ -421,6 +422,20 @@ pipe_dtor(struct pipe *dpipe)
}
}
/*
* Get a timestamp.
*
* This used to be vfs_timestamp but the higher precision is unnecessary and
* can very negatively affect performance in virtualized environments (e.g., on
* vms running on amd64 when using the rdtscp instruction).
*/
static void
pipe_timestamp(struct timespec *tsp)
{
getnanotime(tsp);
}
/*
* The pipe system call for the DTYPE_PIPE type of pipes. If we fail, let
* the zone pick up the pieces via pipeclose().
@ -804,7 +819,7 @@ locked_error:
/* XXX: should probably do this before getting any locks. */
if (error == 0)
vfs_timestamp(&rpipe->pipe_atime);
pipe_timestamp(&rpipe->pipe_atime);
unlocked_error:
--rpipe->pipe_busy;
@ -1290,7 +1305,7 @@ pipe_write(struct file *fp, struct uio *uio, struct ucred *active_cred,
error = 0;
if (error == 0)
vfs_timestamp(&wpipe->pipe_mtime);
pipe_timestamp(&wpipe->pipe_mtime);
/*
* We have something to offer,