From: Christian Schoenebeck <qemu_oss@crudebyte.com>
To: qemu-devel@nongnu.org
Cc: Greg Kurz <groug@kaod.org>
Subject: Re: [PATCH v2 7/7] 9pfs: reduce latency of Twalk
Date: Fri, 02 Jul 2021 17:05:32 +0200 [thread overview]
Message-ID: <16093217.on2isagWAK@silver> (raw)
In-Reply-To: <20210702163656.2b6a8975@bahia.lan>
On Freitag, 2. Juli 2021 16:36:56 CEST Greg Kurz wrote:
> On Fri, 4 Jun 2021 17:38:31 +0200
>
> Christian Schoenebeck <qemu_oss@crudebyte.com> wrote:
> > As with previous performance optimization on Treaddir handling;
> > reduce the overall latency, i.e. overall time spent on processing
> > a Twalk request by reducing the amount of thread hops between the
> > 9p server's main thread and fs worker thread(s).
> >
> > In fact this patch even reduces the thread hops for Twalk handling
> > to its theoritical minimum of exactly 2 thread hops:
> >
> > main thread -> fs worker thread -> main thread
> >
> > This is achieved by doing all the required fs driver tasks altogether
> > in a single v9fs_co_run_in_worker({ ... }); code block.
> >
> > Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
> > ---
> >
> > hw/9pfs/9p.c | 89 +++++++++++++++++++++++++++++++++++++++++-----------
> > 1 file changed, 70 insertions(+), 19 deletions(-)
> >
> > diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
> > index 7be07f2d68..2815257f42 100644
> > --- a/hw/9pfs/9p.c
> > +++ b/hw/9pfs/9p.c
> > @@ -1705,9 +1705,9 @@ static void coroutine_fn v9fs_walk(void *opaque)
> >
> > int name_idx;
> > V9fsQID *qids = NULL;
> > int i, err = 0;
> >
> > - V9fsPath dpath, path;
> > + V9fsPath dpath, path, *pathes = NULL;
> >
> > uint16_t nwnames;
> >
> > - struct stat stbuf;
> > + struct stat stbuf, fidst, *stbufs = NULL;
> >
> > size_t offset = 7;
> > int32_t fid, newfid;
> > V9fsString *wnames = NULL;
> >
> > @@ -1733,6 +1733,8 @@ static void coroutine_fn v9fs_walk(void *opaque)
> >
> > if (nwnames) {
> >
> > wnames = g_new0(V9fsString, nwnames);
> > qids = g_new0(V9fsQID, nwnames);
> >
> > + stbufs = g_new0(struct stat, nwnames);
> > + pathes = g_new0(V9fsPath, nwnames);
> >
> > for (i = 0; i < nwnames; i++) {
> >
> > err = pdu_unmarshal(pdu, offset, "s", &wnames[i]);
> > if (err < 0) {
> >
> > @@ -1753,39 +1755,85 @@ static void coroutine_fn v9fs_walk(void *opaque)
> >
> > v9fs_path_init(&dpath);
> > v9fs_path_init(&path);
> >
> > + /*
> > + * Both dpath and path initially point to fidp.
> > + * Needed to handle request with nwnames == 0
> > + */
> > + v9fs_path_copy(&dpath, &fidp->path);
> > + v9fs_path_copy(&path, &fidp->path);
> >
> > - err = v9fs_co_lstat(pdu, &fidp->path, &stbuf);
> > + /*
> > + * To keep latency (i.e. overall execution time for processing this
> > + * Twalk client request) as small as possible, run all the required
> > fs
> > + * driver code altogether inside the following block.
> > + */
> > + v9fs_co_run_in_worker({
> > + if (v9fs_request_cancelled(pdu)) {
> > + err = -EINTR;
> > + break;
> > + }
> > + err = s->ops->lstat(&s->ctx, &dpath, &fidst);
> > + if (err < 0) {
> > + err = -errno;
> > + break;
> > + }
> > + stbuf = fidst;
> > + for (name_idx = 0; name_idx < nwnames; name_idx++) {
> > + if (v9fs_request_cancelled(pdu)) {
> > + err = -EINTR;
> > + break;
> > + }
> > + if (!same_stat_id(&pdu->s->root_st, &stbuf) ||
> > + strcmp("..", wnames[name_idx].data))
> > + {
> > + err = s->ops->name_to_path(&s->ctx, &dpath,
> > + wnames[name_idx].data, &path);
>
> It seems you could pass &pathes[name_idx] instead of &path and...
>
> > + if (err < 0) {
> > + err = -errno;
> > + break;
> > + }
> > + if (v9fs_request_cancelled(pdu)) {
> > + err = -EINTR;
> > + break;
> > + }
> > + err = s->ops->lstat(&s->ctx, &path, &stbuf);
> > + if (err < 0) {
> > + err = -errno;
> > + break;
> > + }
> > + stbufs[name_idx] = stbuf;
> > + v9fs_path_copy(&dpath, &path);
> > + v9fs_path_copy(&pathes[name_idx], &path);
>
> ... avoid a copy.
It's been a while since I did this, but looks like you are right.
> Also, I believe the path -> dpath could be avoided as well in
> the existing code, but this is a separate cleanup.
>
> > + }
> > + }
> > + });
> > + /*
> > + * Handle all the rest of this Twalk request on main thread ...
> > + */
> >
> > if (err < 0) {
> >
> > goto out;
> >
> > }
> >
> > - err = stat_to_qid(pdu, &stbuf, &qid);
> > +
> > + err = stat_to_qid(pdu, &fidst, &qid);
> >
> > if (err < 0) {
> >
> > goto out;
> >
> > }
> >
> > + stbuf = fidst;
> >
> > - /*
> > - * Both dpath and path initially poin to fidp.
> > - * Needed to handle request with nwnames == 0
> > - */
> > + /* reset dpath and path */
> >
> > v9fs_path_copy(&dpath, &fidp->path);
> > v9fs_path_copy(&path, &fidp->path);
> >
> > +
> >
> > for (name_idx = 0; name_idx < nwnames; name_idx++) {
> >
> > if (!same_stat_id(&pdu->s->root_st, &stbuf) ||
> >
> > - strcmp("..", wnames[name_idx].data)) {
> > - err = v9fs_co_name_to_path(pdu, &dpath,
> > wnames[name_idx].data,
> > - &path);
> > - if (err < 0) {
> > - goto out;
> > - }
> > -
> > - err = v9fs_co_lstat(pdu, &path, &stbuf);
> > - if (err < 0) {
> > - goto out;
> > - }
> > + strcmp("..", wnames[name_idx].data))
> > + {
> > + stbuf = stbufs[name_idx];
> >
> > err = stat_to_qid(pdu, &stbuf, &qid);
> > if (err < 0) {
> >
> > goto out;
> >
> > }
> >
> > + v9fs_path_copy(&path, &pathes[name_idx]);
> >
> > v9fs_path_copy(&dpath, &path);
> >
> > }
> > memcpy(&qids[name_idx], &qid, sizeof(qid));
> >
> > @@ -1821,9 +1869,12 @@ out_nofid:
> > if (nwnames && nwnames <= P9_MAXWELEM) {
> >
> > for (name_idx = 0; name_idx < nwnames; name_idx++) {
> >
> > v9fs_string_free(&wnames[name_idx]);
> >
> > + v9fs_path_free(&pathes[name_idx]);
> >
> > }
> > g_free(wnames);
> > g_free(qids);
> >
> > + g_free(stbufs);
> > + g_free(pathes);
>
> All of these guys should be converted to g_autofree. Separate cleanup
> again.
Definitely agreed on that.
> v9fs_walk() was already a bit hairy and the diffstat definitely
> doesn't improve things... this being said, the change makes sense
> and I haven't spotted anything wrong, so:
>
> Reviewed-by: Greg Kurz <groug@kaod.org>
>
> Improvements could be to :
> - track the previous path with a V9fsPath * instead of copying
> - have a separate path for the nwnames == 0 case
>
> > }
> >
> > }
Yeah, there is a lot more to do on v9fs_walk(), both cleanup, as well as the
previously (couple weeks ago) mentioned protocol fix (i.e. Twalk should only
reply Rerror if there is an error on the very first path element).
If you don't mind, I queue this patch as is for now and prepare a PR for the
current 9p patches in my queue in order to bring them into the soft freeze
deadline.
Thanks for looking at this Greg, I appreciate it!
Best regards,
Christian Schoenebeck
next prev parent reply other threads:[~2021-07-02 15:06 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-04 15:48 [PATCH v2 0/7] 9pfs: Twalk optimization Christian Schoenebeck
2021-05-27 17:03 ` [PATCH v2 2/7] 9pfs: Twalk benchmark Christian Schoenebeck
2021-05-27 17:04 ` [PATCH v2 3/7] 9pfs: capture root stat Christian Schoenebeck
2021-06-04 14:46 ` [PATCH v2 1/7] 9pfs: fix not_same_qid() Christian Schoenebeck
2021-06-04 15:13 ` [PATCH v2 4/7] 9pfs: drop fid_to_qid() Christian Schoenebeck
2021-06-04 15:21 ` [PATCH v2 5/7] 9pfs: replace not_same_qid() by same_stat_id() Christian Schoenebeck
2021-06-04 15:32 ` [PATCH v2 6/7] 9pfs: drop root_qid Christian Schoenebeck
2021-06-04 15:38 ` [PATCH v2 7/7] 9pfs: reduce latency of Twalk Christian Schoenebeck
2021-07-02 14:36 ` Greg Kurz
2021-07-02 15:05 ` Christian Schoenebeck [this message]
2021-07-02 15:26 ` Greg Kurz
2021-06-04 16:31 ` [PATCH v2 0/7] 9pfs: Twalk optimization Greg Kurz
2021-06-04 18:23 ` Christian Schoenebeck
2021-06-28 10:20 ` Christian Schoenebeck
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=16093217.on2isagWAK@silver \
--to=qemu_oss@crudebyte.com \
--cc=groug@kaod.org \
--cc=qemu-devel@nongnu.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 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).