qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 6/6] This patch converts v9fs_walk() to make use of the threadlets infrastructure.
  2010-10-13 15:36 [Qemu-devel] [PATCH 0/6] First threading model Arun R Bharadwaj
@ 2010-10-13 15:38 ` Arun R Bharadwaj
  0 siblings, 0 replies; 9+ messages in thread
From: Arun R Bharadwaj @ 2010-10-13 15:38 UTC (permalink / raw)
  To: qemu-devel

From: Gautham R Shenoy <ego@in.ibm.com>

This patch offloads all the blocking calls invoked for v9fs_walk onto the
helper threads belonging to the threadlets infrastructure. The handling of
the v9fs_post_*walk* calls is done from the io-thread context.

Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
---
 hw/virtio-9p.c |   78 +++++++++++++++++++++++++++++++++++++-------------------
 hw/virtio-9p.h |    5 ++++
 2 files changed, 57 insertions(+), 26 deletions(-)

diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 75d4be3..e95bf50 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -1615,6 +1615,29 @@ out:
     qemu_free(vs);
 }
 
+/************************* v9fs_walk calls *****************************/
+static void v9fs_walk_do_lstat_old(ThreadletWork *work)
+{
+    V9fsWalkState *vs;
+
+    vs = container_of(work, V9fsWalkState, work);
+    vs->err = v9fs_do_lstat(vs->s, &vs->fidp->path, &vs->stbuf);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_walk_do_lstat_new(ThreadletWork *work)
+{
+    V9fsWalkState *vs;
+
+    vs = container_of(work, V9fsWalkState, work);
+    vs->err = v9fs_do_lstat(vs->s, &vs->newfidp->path, &vs->stbuf);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
 static void v9fs_walk_complete(V9fsState *s, V9fsWalkState *vs, int err)
 {
     complete_pdu(s, vs->pdu, err);
@@ -1640,13 +1663,14 @@ static void v9fs_walk_marshal(V9fsWalkState *vs)
     }
 }
 
-static void v9fs_walk_post_newfid_lstat(V9fsState *s, V9fsWalkState *vs,
-                                                                int err)
+static void v9fs_walk_post_newfid_lstat(void *opaque)
 {
-    if (err == -1) {
-        free_fid(s, vs->newfidp->fid);
+    V9fsWalkState *vs = (V9fsWalkState *)opaque;
+
+    if (vs->err == -1) {
+        free_fid(vs->s, vs->newfidp->fid);
         v9fs_string_free(&vs->path);
-        err = -ENOENT;
+        vs->err = -ENOENT;
         goto out;
     }
 
@@ -1658,24 +1682,25 @@ static void v9fs_walk_post_newfid_lstat(V9fsState *s, V9fsWalkState *vs,
                                             vs->wnames[vs->name_idx].data);
         v9fs_string_copy(&vs->newfidp->path, &vs->path);
 
-        err = v9fs_do_lstat(s, &vs->newfidp->path, &vs->stbuf);
-        v9fs_walk_post_newfid_lstat(s, vs, err);
+        v9fs_do_async_posix(&vs->work, v9fs_walk_do_lstat_new, &vs->post_fn,
+                            v9fs_walk_post_newfid_lstat);
         return;
     }
 
     v9fs_string_free(&vs->path);
     v9fs_walk_marshal(vs);
-    err = vs->offset;
+    vs->err = vs->offset;
 out:
-    v9fs_walk_complete(s, vs, err);
+    v9fs_walk_complete(vs->s, vs, vs->err);
 }
 
-static void v9fs_walk_post_oldfid_lstat(V9fsState *s, V9fsWalkState *vs,
-        int err)
+static void v9fs_walk_post_oldfid_lstat(void *opaque)
 {
-    if (err == -1) {
+    V9fsWalkState *vs = (V9fsWalkState *)opaque;
+
+    if (vs->err == -1) {
         v9fs_string_free(&vs->path);
-        err = -ENOENT;
+        vs->err = -ENOENT;
         goto out;
     }
 
@@ -1687,23 +1712,22 @@ static void v9fs_walk_post_oldfid_lstat(V9fsState *s, V9fsWalkState *vs,
                 vs->fidp->path.data, vs->wnames[vs->name_idx].data);
         v9fs_string_copy(&vs->fidp->path, &vs->path);
 
-        err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
-        v9fs_walk_post_oldfid_lstat(s, vs, err);
+        v9fs_do_async_posix(&vs->work, v9fs_walk_do_lstat_old, &vs->post_fn,
+                            v9fs_walk_post_oldfid_lstat);
         return;
     }
 
     v9fs_string_free(&vs->path);
     v9fs_walk_marshal(vs);
-    err = vs->offset;
+    vs->err = vs->offset;
 out:
-    v9fs_walk_complete(s, vs, err);
+    v9fs_walk_complete(vs->s, vs, vs->err);
 }
 
 static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
 {
     int32_t fid, newfid;
     V9fsWalkState *vs;
-    int err = 0;
     int i;
 
     vs = qemu_malloc(sizeof(*vs));
@@ -1711,6 +1735,8 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
     vs->wnames = NULL;
     vs->qids = NULL;
     vs->offset = 7;
+    vs->err = 0;
+    vs->s = s;
 
     vs->offset += pdu_unmarshal(vs->pdu, vs->offset, "ddw", &fid,
                                             &newfid, &vs->nwnames);
@@ -1728,7 +1754,7 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
 
     vs->fidp = lookup_fid(s, fid);
     if (vs->fidp == NULL) {
-        err = -ENOENT;
+        vs->err = -ENOENT;
         goto out;
     }
 
@@ -1744,14 +1770,14 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
                 vs->fidp->path.data, vs->wnames[vs->name_idx].data);
             v9fs_string_copy(&vs->fidp->path, &vs->path);
 
-            err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
-            v9fs_walk_post_oldfid_lstat(s, vs, err);
+            v9fs_do_async_posix(&vs->work, v9fs_walk_do_lstat_old,
+                                &vs->post_fn, v9fs_walk_post_oldfid_lstat);
             return;
         }
     } else {
         vs->newfidp = alloc_fid(s, newfid);
         if (vs->newfidp == NULL) {
-            err = -EINVAL;
+            vs->err = -EINVAL;
             goto out;
         }
 
@@ -1765,16 +1791,16 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
                                 vs->wnames[vs->name_idx].data);
             v9fs_string_copy(&vs->newfidp->path, &vs->path);
 
-            err = v9fs_do_lstat(s, &vs->newfidp->path, &vs->stbuf);
-            v9fs_walk_post_newfid_lstat(s, vs, err);
+            v9fs_do_async_posix(&vs->work, v9fs_walk_do_lstat_new,
+                                &vs->post_fn, v9fs_walk_post_newfid_lstat);
             return;
         }
     }
 
     v9fs_walk_marshal(vs);
-    err = vs->offset;
+    vs->err = vs->offset;
 out:
-    v9fs_walk_complete(s, vs, err);
+    v9fs_walk_complete(s, vs, vs->err);
 }
 
 /********************* v9fs_open calls *********************************/
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index 294de83..f88b5fc 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -296,6 +296,11 @@ typedef struct V9fsWalkState {
     V9fsString path;
     V9fsString *wnames;
     struct stat stbuf;
+    V9fsState *s;
+    int err;
+    int v9fs_errno;
+    ThreadletWork work;
+    void (*post_fn)(void *arg);
 } V9fsWalkState;
 
 typedef struct V9fsOpenState {

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

* [Qemu-devel] [PATCH 6/6] This patch converts v9fs_walk() to make use of the threadlets infrastructure.
  2010-10-13 17:09 [Qemu-devel] [RFC PATCH 0/6] First Threading Model Arun R Bharadwaj
@ 2010-10-13 17:10 ` Arun R Bharadwaj
  0 siblings, 0 replies; 9+ messages in thread
From: Arun R Bharadwaj @ 2010-10-13 17:10 UTC (permalink / raw)
  To: qemu-devel

From: Gautham R Shenoy <ego@in.ibm.com>

This patch offloads all the blocking calls invoked for v9fs_walk onto the
helper threads belonging to the threadlets infrastructure. The handling of
the v9fs_post_*walk* calls is done from the io-thread context.

Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
---
 hw/virtio-9p.c |   78 +++++++++++++++++++++++++++++++++++++-------------------
 hw/virtio-9p.h |    5 ++++
 2 files changed, 57 insertions(+), 26 deletions(-)

diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 75d4be3..e95bf50 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -1615,6 +1615,29 @@ out:
     qemu_free(vs);
 }
 
+/************************* v9fs_walk calls *****************************/
+static void v9fs_walk_do_lstat_old(ThreadletWork *work)
+{
+    V9fsWalkState *vs;
+
+    vs = container_of(work, V9fsWalkState, work);
+    vs->err = v9fs_do_lstat(vs->s, &vs->fidp->path, &vs->stbuf);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_walk_do_lstat_new(ThreadletWork *work)
+{
+    V9fsWalkState *vs;
+
+    vs = container_of(work, V9fsWalkState, work);
+    vs->err = v9fs_do_lstat(vs->s, &vs->newfidp->path, &vs->stbuf);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
 static void v9fs_walk_complete(V9fsState *s, V9fsWalkState *vs, int err)
 {
     complete_pdu(s, vs->pdu, err);
@@ -1640,13 +1663,14 @@ static void v9fs_walk_marshal(V9fsWalkState *vs)
     }
 }
 
-static void v9fs_walk_post_newfid_lstat(V9fsState *s, V9fsWalkState *vs,
-                                                                int err)
+static void v9fs_walk_post_newfid_lstat(void *opaque)
 {
-    if (err == -1) {
-        free_fid(s, vs->newfidp->fid);
+    V9fsWalkState *vs = (V9fsWalkState *)opaque;
+
+    if (vs->err == -1) {
+        free_fid(vs->s, vs->newfidp->fid);
         v9fs_string_free(&vs->path);
-        err = -ENOENT;
+        vs->err = -ENOENT;
         goto out;
     }
 
@@ -1658,24 +1682,25 @@ static void v9fs_walk_post_newfid_lstat(V9fsState *s, V9fsWalkState *vs,
                                             vs->wnames[vs->name_idx].data);
         v9fs_string_copy(&vs->newfidp->path, &vs->path);
 
-        err = v9fs_do_lstat(s, &vs->newfidp->path, &vs->stbuf);
-        v9fs_walk_post_newfid_lstat(s, vs, err);
+        v9fs_do_async_posix(&vs->work, v9fs_walk_do_lstat_new, &vs->post_fn,
+                            v9fs_walk_post_newfid_lstat);
         return;
     }
 
     v9fs_string_free(&vs->path);
     v9fs_walk_marshal(vs);
-    err = vs->offset;
+    vs->err = vs->offset;
 out:
-    v9fs_walk_complete(s, vs, err);
+    v9fs_walk_complete(vs->s, vs, vs->err);
 }
 
-static void v9fs_walk_post_oldfid_lstat(V9fsState *s, V9fsWalkState *vs,
-        int err)
+static void v9fs_walk_post_oldfid_lstat(void *opaque)
 {
-    if (err == -1) {
+    V9fsWalkState *vs = (V9fsWalkState *)opaque;
+
+    if (vs->err == -1) {
         v9fs_string_free(&vs->path);
-        err = -ENOENT;
+        vs->err = -ENOENT;
         goto out;
     }
 
@@ -1687,23 +1712,22 @@ static void v9fs_walk_post_oldfid_lstat(V9fsState *s, V9fsWalkState *vs,
                 vs->fidp->path.data, vs->wnames[vs->name_idx].data);
         v9fs_string_copy(&vs->fidp->path, &vs->path);
 
-        err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
-        v9fs_walk_post_oldfid_lstat(s, vs, err);
+        v9fs_do_async_posix(&vs->work, v9fs_walk_do_lstat_old, &vs->post_fn,
+                            v9fs_walk_post_oldfid_lstat);
         return;
     }
 
     v9fs_string_free(&vs->path);
     v9fs_walk_marshal(vs);
-    err = vs->offset;
+    vs->err = vs->offset;
 out:
-    v9fs_walk_complete(s, vs, err);
+    v9fs_walk_complete(vs->s, vs, vs->err);
 }
 
 static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
 {
     int32_t fid, newfid;
     V9fsWalkState *vs;
-    int err = 0;
     int i;
 
     vs = qemu_malloc(sizeof(*vs));
@@ -1711,6 +1735,8 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
     vs->wnames = NULL;
     vs->qids = NULL;
     vs->offset = 7;
+    vs->err = 0;
+    vs->s = s;
 
     vs->offset += pdu_unmarshal(vs->pdu, vs->offset, "ddw", &fid,
                                             &newfid, &vs->nwnames);
@@ -1728,7 +1754,7 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
 
     vs->fidp = lookup_fid(s, fid);
     if (vs->fidp == NULL) {
-        err = -ENOENT;
+        vs->err = -ENOENT;
         goto out;
     }
 
@@ -1744,14 +1770,14 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
                 vs->fidp->path.data, vs->wnames[vs->name_idx].data);
             v9fs_string_copy(&vs->fidp->path, &vs->path);
 
-            err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
-            v9fs_walk_post_oldfid_lstat(s, vs, err);
+            v9fs_do_async_posix(&vs->work, v9fs_walk_do_lstat_old,
+                                &vs->post_fn, v9fs_walk_post_oldfid_lstat);
             return;
         }
     } else {
         vs->newfidp = alloc_fid(s, newfid);
         if (vs->newfidp == NULL) {
-            err = -EINVAL;
+            vs->err = -EINVAL;
             goto out;
         }
 
@@ -1765,16 +1791,16 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
                                 vs->wnames[vs->name_idx].data);
             v9fs_string_copy(&vs->newfidp->path, &vs->path);
 
-            err = v9fs_do_lstat(s, &vs->newfidp->path, &vs->stbuf);
-            v9fs_walk_post_newfid_lstat(s, vs, err);
+            v9fs_do_async_posix(&vs->work, v9fs_walk_do_lstat_new,
+                                &vs->post_fn, v9fs_walk_post_newfid_lstat);
             return;
         }
     }
 
     v9fs_walk_marshal(vs);
-    err = vs->offset;
+    vs->err = vs->offset;
 out:
-    v9fs_walk_complete(s, vs, err);
+    v9fs_walk_complete(s, vs, vs->err);
 }
 
 /********************* v9fs_open calls *********************************/
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index 294de83..f88b5fc 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -296,6 +296,11 @@ typedef struct V9fsWalkState {
     V9fsString path;
     V9fsString *wnames;
     struct stat stbuf;
+    V9fsState *s;
+    int err;
+    int v9fs_errno;
+    ThreadletWork work;
+    void (*post_fn)(void *arg);
 } V9fsWalkState;
 
 typedef struct V9fsOpenState {

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

* [Qemu-devel] [RFC PATCH 0/6] First threading model
@ 2010-10-13 17:20 Arun R Bharadwaj
  2010-10-13 17:21 ` [Qemu-devel] [PATCH 1/6] This patch converts v9fs_stat() to make use of the threadlets infrastructure Arun R Bharadwaj
                   ` (5 more replies)
  0 siblings, 6 replies; 9+ messages in thread
From: Arun R Bharadwaj @ 2010-10-13 17:20 UTC (permalink / raw)
  To: qemu-devel

This patchset implements first threading model by making use
of the threadlets infrastructure being discussed here:
http://www.mail-archive.com/qemu-devel@nongnu.org/msg36678.html

Here are some of the performance results comparing between the
original code and threading model code:
http://pastebin.com/EzdJRC34


Following are the features of the first threading model:

* The VCPU thread runs the Qemu code until the first blocking
  call is encountered.

* The work to be done in the blocking call is assigned to an
  asynchronous thread and the VCPU thread continues running
  the Qemu code.

* The aynchronous thread reports back to the VCPU/IO thread
  when the blocking call is finished.

* The VCPU/IO thread continues from immediately after the
  blocking call until the next blocking call is hit, and
  the whole process is repeated till no blocking call is
  encountered.

The following series implements...

---

Gautham R Shenoy (6):
      This patch converts v9fs_stat() to make use of the threadlets infrastructure.
      This patch converts v9fs_wstat() to make use of the threadlets infrastructure.
      This patch converts v9fs_read() to make use of the threadlets infrastructure.
      This patch converts v9fs_write() to make use of the threadlets infrastructure.
      This patch converts v9fs_open() to make use of the threadlets infrastructure.
      This patch converts v9fs_walk() to make use of the threadlets infrastructure.


 hw/virtio-9p.c |  770 +++++++++++++++++++++++++++++++++++++++++---------------
 hw/virtio-9p.h |   33 ++
 2 files changed, 597 insertions(+), 206 deletions(-)

-- 
arun

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

* [Qemu-devel] [PATCH 1/6] This patch converts v9fs_stat() to make use of the threadlets infrastructure.
  2010-10-13 17:20 [Qemu-devel] [RFC PATCH 0/6] First threading model Arun R Bharadwaj
@ 2010-10-13 17:21 ` Arun R Bharadwaj
  2010-10-13 17:21 ` [Qemu-devel] [PATCH 2/6] This patch converts v9fs_wstat() " Arun R Bharadwaj
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Arun R Bharadwaj @ 2010-10-13 17:21 UTC (permalink / raw)
  To: qemu-devel

From: Gautham R Shenoy <ego@in.ibm.com>

Every call to v9fs_stat() is processed in the context of the vcpu thread before
offloading the actual stat operation onto an async-thread. The post operation is
handled in the context of the io-thread which in turn does the complete()
operation for this particular v9fs_stat() operation.

Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
---
 hw/virtio-9p.c |   34 ++++++++++++++++++++++------------
 hw/virtio-9p.h |    6 ++++++
 2 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 174300d..5f6ce56 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -1356,26 +1356,38 @@ out:
     v9fs_string_free(&aname);
 }
 
-static void v9fs_stat_post_lstat(V9fsState *s, V9fsStatState *vs, int err)
+static void v9fs_stat_post_lstat(void *opaque)
 {
-    if (err == -1) {
-        err = -errno;
+    V9fsStatState *vs = (V9fsStatState *)opaque;
+
+    if (vs->err == -1) {
+        vs->err = -(vs->v9fs_errno);
         goto out;
     }
 
-    err = stat_to_v9stat(s, &vs->fidp->path, &vs->stbuf, &vs->v9stat);
-    if (err) {
+    vs->err = stat_to_v9stat(vs->s, &vs->fidp->path, &vs->stbuf, &vs->v9stat);
+    if (vs->err) {
         goto out;
     }
     vs->offset += pdu_marshal(vs->pdu, vs->offset, "wS", 0, &vs->v9stat);
-    err = vs->offset;
+    vs->err = vs->offset;
 
 out:
-    complete_pdu(s, vs->pdu, err);
+    complete_pdu(vs->s, vs->pdu, vs->err);
     v9fs_stat_free(&vs->v9stat);
     qemu_free(vs);
 }
 
+static void v9fs_stat_do_lstat(ThreadletWork *work)
+{
+    V9fsStatState *vs = container_of(work, V9fsStatState, work);
+
+    vs->err = v9fs_do_lstat(vs->s, &vs->fidp->path, &vs->stbuf);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
 static void v9fs_stat(V9fsState *s, V9fsPDU *pdu)
 {
     int32_t fid;
@@ -1385,6 +1397,7 @@ static void v9fs_stat(V9fsState *s, V9fsPDU *pdu)
     vs = qemu_malloc(sizeof(*vs));
     vs->pdu = pdu;
     vs->offset = 7;
+    vs->s = s;
 
     memset(&vs->v9stat, 0, sizeof(vs->v9stat));
 
@@ -1396,8 +1409,8 @@ static void v9fs_stat(V9fsState *s, V9fsPDU *pdu)
         goto out;
     }
 
-    err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
-    v9fs_stat_post_lstat(s, vs, err);
+    v9fs_do_async_posix(&vs->work, v9fs_stat_do_lstat, &vs->post_fn,
+                        v9fs_stat_post_lstat);
     return;
 
 out:
@@ -3882,8 +3895,5 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
     qemu_mutex_init(&(v9fs_async_struct.lock));
     /* Create async queue. */
 
-    (void)v9fs_do_async_posix;
-    (void)v9fs_async_helper_done;
-
     return &s->vdev;
 }
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index 6c23319..769d3fc 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -7,6 +7,7 @@
 #include <utime.h>
 
 #include "file-op-9p.h"
+#include "qemu-threadlets.h"
 
 /* The feature bitmap for virtio 9P */
 /* The mount point is specified in a config variable */
@@ -246,6 +247,11 @@ typedef struct V9fsStatState {
     V9fsStat v9stat;
     V9fsFidState *fidp;
     struct stat stbuf;
+    V9fsState *s;
+    int err;
+    int v9fs_errno;
+    ThreadletWork work;
+    void (*post_fn)(void *arg);
 } V9fsStatState;
 
 typedef struct V9fsStatDotl {

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

* [Qemu-devel] [PATCH 2/6] This patch converts v9fs_wstat() to make use of the threadlets infrastructure.
  2010-10-13 17:20 [Qemu-devel] [RFC PATCH 0/6] First threading model Arun R Bharadwaj
  2010-10-13 17:21 ` [Qemu-devel] [PATCH 1/6] This patch converts v9fs_stat() to make use of the threadlets infrastructure Arun R Bharadwaj
@ 2010-10-13 17:21 ` Arun R Bharadwaj
  2010-10-13 17:22 ` [Qemu-devel] [PATCH 3/6] This patch converts v9fs_read() " Arun R Bharadwaj
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Arun R Bharadwaj @ 2010-10-13 17:21 UTC (permalink / raw)
  To: qemu-devel

From: Gautham R Shenoy <ego@in.ibm.com>

This patch offloads all the blocking calls invoked for v9fs_wstat onto
the helper threads belonging to the threadlets infrastructure.The handling
of the v9fs_post_*wstat* calls is done from the io-thread context.

Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
---
 hw/virtio-9p.c |  291 +++++++++++++++++++++++++++++++++++++++++++++-----------
 hw/virtio-9p.h |    7 +
 2 files changed, 243 insertions(+), 55 deletions(-)

diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 5f6ce56..cf7e012 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -2853,36 +2853,126 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_wstat_post_truncate(V9fsState *s, V9fsWstatState *vs, int err)
+/*********************** v9fs_wstat operations ************************/
+
+static void v9fs_wstat_do_fsync(ThreadletWork *work)
+ {
+    V9fsWstatState *vs;
+
+    vs = container_of(work, V9fsWstatState, work);
+    vs->err = v9fs_do_fsync(vs->s, vs->fidp->fs.fd);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_wstat_do_lstat(ThreadletWork *work)
 {
-    if (err < 0) {
+    V9fsWstatState *vs;
+
+    vs = container_of(work, V9fsWstatState, work);
+    vs->err = v9fs_do_lstat(vs->s, &vs->fidp->path, &vs->stbuf);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_wstat_do_utimensat(ThreadletWork *work)
+{
+    V9fsWstatState *vs;
+
+    vs = container_of(work, V9fsWstatState, work);
+    vs->err = v9fs_do_utimensat(vs->s, &vs->fidp->path, vs->times);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+
+}
+
+static void v9fs_wstat_do_chmod(ThreadletWork *work)
+{
+    V9fsWstatState *vs;
+
+    vs = container_of(work, V9fsWstatState, work);
+    vs->err = v9fs_do_chmod(vs->s, &vs->fidp->path,
+                      v9mode_to_mode(vs->v9stat.mode,
+                      &vs->v9stat.extension));
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_wstat_do_chown(ThreadletWork *work)
+{
+    V9fsWstatState *vs;
+
+    vs = container_of(work, V9fsWstatState, work);
+    vs->err = v9fs_do_chown(vs->s, &vs->fidp->path, vs->v9stat.n_uid,
+                            vs->v9stat.n_gid);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_wstat_do_rename(ThreadletWork *work)
+{
+    V9fsWstatState *vs;
+
+    vs = container_of(work, V9fsWstatState, work);
+    vs->err = v9fs_do_rename(vs->s, &vs->fidp->path, &vs->nname);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_wstat_do_truncate(ThreadletWork *work)
+{
+    V9fsWstatState *vs;
+
+    vs = container_of(work, V9fsWstatState, work);
+    vs->err = v9fs_do_truncate(vs->s, &vs->fidp->path,
+                               vs->v9stat.length);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_wstat_post_truncate(void *opaque)
+{
+    V9fsWstatState *vs = (V9fsWstatState *)opaque;
+
+    if (vs->err < 0) {
+        vs->err = -vs->v9fs_errno;
         goto out;
     }
 
-    err = vs->offset;
+    vs->err = vs->offset;
 
 out:
     v9fs_stat_free(&vs->v9stat);
-    complete_pdu(s, vs->pdu, err);
+    complete_pdu(vs->s, vs->pdu, vs->err);
     qemu_free(vs);
 }
 
-static void v9fs_wstat_post_rename(V9fsState *s, V9fsWstatState *vs, int err)
+static void v9fs_wstat_post_rename(void *opaque)
 {
-    if (err < 0) {
+     V9fsWstatState *vs = (V9fsWstatState *)opaque;
+
+    if (vs->err < 0) {
+        vs->err = -vs->v9fs_errno;
         goto out;
     }
     if (vs->v9stat.length != -1) {
-        if (v9fs_do_truncate(s, &vs->fidp->path, vs->v9stat.length) < 0) {
-            err = -errno;
-        }
+        v9fs_do_async_posix(&vs->work, v9fs_wstat_do_truncate,
+                            &vs->post_fn, v9fs_wstat_post_truncate);
+        return;
     }
-    v9fs_wstat_post_truncate(s, vs, err);
+    v9fs_wstat_post_truncate(vs);
     return;
 
 out:
     v9fs_stat_free(&vs->v9stat);
-    complete_pdu(s, vs->pdu, err);
+    complete_pdu(vs->s, vs->pdu, vs->err);
     qemu_free(vs);
 }
 
@@ -2964,6 +3054,7 @@ static void v9fs_rename_post_rename(V9fsState *s, V9fsRenameState *vs, int err)
     qemu_free(vs);
 }
 
+#if 0
 static void v9fs_wstat_post_chown(V9fsState *s, V9fsWstatState *vs, int err)
 {
     if (err < 0) {
@@ -2992,6 +3083,91 @@ out:
     complete_pdu(s, vs->pdu, err);
     qemu_free(vs);
 }
+#endif
+
+static void v9fs_wstat_post_rename_new(void *opaque)
+{
+    V9fsWstatState *vs = (V9fsWstatState *)opaque;
+    V9fsFidState *fidp;
+
+    if (vs->err < 0) {
+        vs->err = -vs->v9fs_errno;
+        goto out;
+    }
+
+    /*
+     * Fixup fid's pointing to the old name to
+     * start pointing to the new name
+     */
+    for (fidp = vs->s->fid_list; fidp; fidp = fidp->next) {
+        if (vs->fidp == fidp) {
+            /*
+             * we replace name of this fid towards the end
+             * so that our below strcmp will work
+             */
+            continue;
+        }
+        if (!strncmp(vs->fidp->path.data, fidp->path.data,
+            strlen(vs->fidp->path.data))) {
+            /* replace the name */
+            v9fs_fix_path(&fidp->path, &vs->nname,
+            strlen(vs->fidp->path.data));
+        }
+    }
+
+    v9fs_string_copy(&vs->fidp->path, &vs->nname);
+
+out:
+    v9fs_wstat_post_rename(vs);
+    return;
+}
+
+static void v9fs_wstat_post_chown(void *opaque)
+{
+    V9fsWstatState *vs = (V9fsWstatState *)opaque;
+
+    if (vs->err < 0) {
+        vs->err = -vs->v9fs_errno;
+        goto out;
+    }
+
+    if (vs->v9stat.name.size != 0) {
+        char *old_name, *new_name;
+        char *end;
+
+        old_name = vs->fidp->path.data;
+        end = strrchr(old_name, '/');
+        if (end) {
+            end++;
+        } else {
+            end = old_name;
+        }
+
+        new_name = qemu_malloc(end - old_name + vs->v9stat.name.size + 1);
+
+        memset(new_name, 0, end - old_name + vs->v9stat.name.size + 1);
+        memcpy(new_name, old_name, end - old_name);
+        memcpy(new_name + (end - old_name), vs->v9stat.name.data,
+                vs->v9stat.name.size);
+        vs->nname.data = new_name;
+        vs->nname.size = strlen(new_name);
+
+        if (strcmp(new_name, vs->fidp->path.data) != 0) {
+            v9fs_do_async_posix(&vs->work, v9fs_wstat_do_rename,
+                                &vs->post_fn, v9fs_wstat_post_rename_new);
+            return;
+        }
+    }
+
+    v9fs_wstat_post_rename(vs);
+    return;
+
+out:
+    v9fs_stat_free(&vs->v9stat);
+    complete_pdu(vs->s, vs->pdu, vs->err);
+    qemu_free(vs);
+}
+
 
 static void v9fs_rename(V9fsState *s, V9fsPDU *pdu)
 {
@@ -3021,78 +3197,85 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_wstat_post_utime(V9fsState *s, V9fsWstatState *vs, int err)
+static void v9fs_wstat_post_utime(void *opaque)
 {
-    if (err < 0) {
+    V9fsWstatState *vs = (V9fsWstatState *)opaque;
+
+    if (vs->err < 0) {
+        vs->err = -vs->v9fs_errno;
         goto out;
     }
 
     if (vs->v9stat.n_gid != -1 || vs->v9stat.n_uid != -1) {
-        if (v9fs_do_chown(s, &vs->fidp->path, vs->v9stat.n_uid,
-                    vs->v9stat.n_gid)) {
-            err = -errno;
-        }
+        v9fs_do_async_posix(&vs->work, v9fs_wstat_do_chown, &vs->post_fn,
+                            v9fs_wstat_post_chown);
+        return;
     }
-    v9fs_wstat_post_chown(s, vs, err);
+    v9fs_wstat_post_chown(vs);
     return;
 
 out:
     v9fs_stat_free(&vs->v9stat);
-    complete_pdu(s, vs->pdu, err);
+    complete_pdu(vs->s, vs->pdu, vs->err);
     qemu_free(vs);
 }
 
-static void v9fs_wstat_post_chmod(V9fsState *s, V9fsWstatState *vs, int err)
+static void v9fs_wstat_post_chmod(void *opaque)
 {
-    if (err < 0) {
+    V9fsWstatState *vs = (V9fsWstatState *)opaque;
+
+    if (vs->err < 0) {
+        vs->err = -vs->v9fs_errno;
         goto out;
     }
 
     if (vs->v9stat.mtime != -1 || vs->v9stat.atime != -1) {
-        struct timespec times[2];
         if (vs->v9stat.atime != -1) {
-            times[0].tv_sec = vs->v9stat.atime;
-            times[0].tv_nsec = 0;
+            vs->times[0].tv_sec = vs->v9stat.atime;
+            vs->times[0].tv_nsec = 0;
         } else {
-            times[0].tv_nsec = UTIME_OMIT;
+            vs->times[0].tv_nsec = UTIME_OMIT;
         }
         if (vs->v9stat.mtime != -1) {
-            times[1].tv_sec = vs->v9stat.mtime;
-            times[1].tv_nsec = 0;
+            vs->times[1].tv_sec = vs->v9stat.mtime;
+            vs->times[1].tv_nsec = 0;
         } else {
-            times[1].tv_nsec = UTIME_OMIT;
+            vs->times[1].tv_nsec = UTIME_OMIT;
         }
 
-        if (v9fs_do_utimensat(s, &vs->fidp->path, times)) {
-            err = -errno;
-        }
+        v9fs_do_async_posix(&vs->work, v9fs_wstat_do_utimensat,
+                            &vs->post_fn, v9fs_wstat_post_utime);
+        return;
     }
 
-    v9fs_wstat_post_utime(s, vs, err);
+    v9fs_wstat_post_utime(vs);
     return;
 
 out:
     v9fs_stat_free(&vs->v9stat);
-    complete_pdu(s, vs->pdu, err);
+    complete_pdu(vs->s, vs->pdu, vs->err);
     qemu_free(vs);
 }
 
-static void v9fs_wstat_post_fsync(V9fsState *s, V9fsWstatState *vs, int err)
+static void v9fs_wstat_post_fsync(void *opaque)
 {
-    if (err == -1) {
-        err = -errno;
+    V9fsWstatState *vs = (V9fsWstatState *)opaque;
+
+    if (vs->err == -1) {
+        vs->err = -vs->v9fs_errno;
     }
     v9fs_stat_free(&vs->v9stat);
-    complete_pdu(s, vs->pdu, err);
+    complete_pdu(vs->s, vs->pdu, vs->err);
     qemu_free(vs);
 }
 
-static void v9fs_wstat_post_lstat(V9fsState *s, V9fsWstatState *vs, int err)
+static void v9fs_wstat_post_lstat(void *opaque)
 {
     uint32_t v9_mode;
+    V9fsWstatState *vs = (V9fsWstatState *)opaque;
 
-    if (err == -1) {
-        err = -errno;
+    if (vs->err == -1) {
+        vs->err = -vs->v9fs_errno;
         goto out;
     }
 
@@ -3101,20 +3284,17 @@ static void v9fs_wstat_post_lstat(V9fsState *s, V9fsWstatState *vs, int err)
     if ((vs->v9stat.mode & P9_STAT_MODE_TYPE_BITS) !=
         (v9_mode & P9_STAT_MODE_TYPE_BITS)) {
             /* Attempting to change the type */
-            err = -EIO;
+            vs->err = -EIO;
             goto out;
     }
 
-    if (v9fs_do_chmod(s, &vs->fidp->path, v9mode_to_mode(vs->v9stat.mode,
-                    &vs->v9stat.extension))) {
-            err = -errno;
-     }
-    v9fs_wstat_post_chmod(s, vs, err);
+    v9fs_do_async_posix(&vs->work, v9fs_wstat_do_chmod, &vs->post_fn,
+                        v9fs_wstat_post_chmod);
     return;
 
 out:
     v9fs_stat_free(&vs->v9stat);
-    complete_pdu(s, vs->pdu, err);
+    complete_pdu(vs->s, vs->pdu, vs->err);
     qemu_free(vs);
 }
 
@@ -3122,39 +3302,40 @@ static void v9fs_wstat(V9fsState *s, V9fsPDU *pdu)
 {
     int32_t fid;
     V9fsWstatState *vs;
-    int err = 0;
 
     vs = qemu_malloc(sizeof(*vs));
     vs->pdu = pdu;
     vs->offset = 7;
+    vs->s = s;
+    vs->err = 0;
 
     pdu_unmarshal(pdu, vs->offset, "dwS", &fid, &vs->unused, &vs->v9stat);
 
     vs->fidp = lookup_fid(s, fid);
     if (vs->fidp == NULL) {
-        err = -EINVAL;
+        vs->err = -EINVAL;
         goto out;
     }
 
     /* do we need to sync the file? */
     if (donttouch_stat(&vs->v9stat)) {
-        err = v9fs_do_fsync(s, vs->fidp->fs.fd);
-        v9fs_wstat_post_fsync(s, vs, err);
+        v9fs_do_async_posix(&vs->work, v9fs_wstat_do_fsync, &vs->post_fn,
+                            v9fs_wstat_post_fsync);
         return;
     }
 
     if (vs->v9stat.mode != -1) {
-        err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
-        v9fs_wstat_post_lstat(s, vs, err);
+        v9fs_do_async_posix(&vs->work, v9fs_wstat_do_lstat, &vs->post_fn,
+                            v9fs_wstat_post_lstat);
         return;
     }
 
-    v9fs_wstat_post_chmod(s, vs, err);
+    v9fs_wstat_post_chmod(vs);
     return;
 
 out:
     v9fs_stat_free(&vs->v9stat);
-    complete_pdu(s, vs->pdu, err);
+    complete_pdu(s, vs->pdu, vs->err);
     qemu_free(vs);
 }
 
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index 769d3fc..74d7b68 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -354,6 +354,13 @@ typedef struct V9fsWstatState
     V9fsStat v9stat;
     V9fsFidState *fidp;
     struct stat stbuf;
+    V9fsString nname;
+    V9fsState *s;
+    int err;
+    int v9fs_errno;
+    struct timespec times[2];
+    ThreadletWork work;
+    void (*post_fn)(void *arg);
 } V9fsWstatState;
 
 typedef struct V9fsSymlinkState

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

* [Qemu-devel] [PATCH 3/6] This patch converts v9fs_read() to make use of the threadlets infrastructure.
  2010-10-13 17:20 [Qemu-devel] [RFC PATCH 0/6] First threading model Arun R Bharadwaj
  2010-10-13 17:21 ` [Qemu-devel] [PATCH 1/6] This patch converts v9fs_stat() to make use of the threadlets infrastructure Arun R Bharadwaj
  2010-10-13 17:21 ` [Qemu-devel] [PATCH 2/6] This patch converts v9fs_wstat() " Arun R Bharadwaj
@ 2010-10-13 17:22 ` Arun R Bharadwaj
  2010-10-13 17:22 ` [Qemu-devel] [PATCH 4/6] This patch converts v9fs_write() " Arun R Bharadwaj
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Arun R Bharadwaj @ 2010-10-13 17:22 UTC (permalink / raw)
  To: qemu-devel

From: Gautham R Shenoy <ego@in.ibm.com>

This patch offloads all the blocking calls invoked for v9fs_read onto the
helper threads belonging to the threadlets infrastructure. The handling of
the v9fs_post_*read* calls is done from the io-thread context.

Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
Signed-off-by: Arun R Bharadwaj <arun@linux.vnet.ibm.com>
---
 hw/virtio-9p.c |  218 +++++++++++++++++++++++++++++++++++++++++---------------
 hw/virtio-9p.h |    5 +
 2 files changed, 164 insertions(+), 59 deletions(-)

diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index cf7e012..da185c3 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -2037,33 +2037,136 @@ out:
     complete_pdu(s, pdu, err);
 }
 
-static void v9fs_read_post_readdir(V9fsState *, V9fsReadState *, ssize_t);
+/********************** v9fs_read calls ******************************/
+static void v9fs_read_do_preadv(ThreadletWork *work)
+{
+    V9fsReadState *vs;
+
+    vs = container_of(work, V9fsReadState, work);
+    v9fs_do_preadv(vs->s, vs->fidp->fs.fd, vs->sg, vs->cnt, vs->off);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_read_do_rewinddir(ThreadletWork *work)
+ {
+    V9fsReadState *vs;
+
+    vs = container_of(work, V9fsReadState, work);
+    v9fs_do_rewinddir(vs->s, vs->fidp->fs.dir);
+    vs->v9fs_errno = errno;
 
-static void v9fs_read_post_seekdir(V9fsState *s, V9fsReadState *vs, ssize_t err)
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_read_do_lseek(ThreadletWork *work)
 {
-    if (err) {
+    V9fsReadState *vs;
+
+    vs = container_of(work, V9fsReadState, work);
+    vs->err = v9fs_do_lseek(vs->s, vs->fidp->fs.fd, vs->off, SEEK_SET);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_read_do_readv(ThreadletWork *work)
+{
+    V9fsReadState *vs;
+
+    vs = container_of(work, V9fsReadState, work);
+    do {
+        if (0) {
+            print_sg(vs->sg, vs->cnt);
+        }
+        vs->len = v9fs_do_readv(vs->s, vs->fidp->fs.fd, vs->sg, vs->cnt);
+    } while (vs->len == -1 && errno == EINTR);
+    vs->v9fs_errno = errno;
+
+    if (vs->len == -1) {
+        vs->err  = -vs->v9fs_errno;
+    }
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_read_do_telldir(ThreadletWork *work)
+{
+    V9fsReadState *vs;
+
+    vs = container_of(work, V9fsReadState, work);
+    vs->dir_pos = v9fs_do_telldir(vs->s, vs->fidp->fs.dir);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_read_do_readdir(ThreadletWork *work)
+{
+    V9fsReadState *vs;
+
+    vs = container_of(work, V9fsReadState, work);
+    vs->dent = v9fs_do_readdir(vs->s, vs->fidp->fs.dir);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_read_do_lstat(ThreadletWork *work)
+{
+    V9fsReadState *vs;
+
+    vs = container_of(work, V9fsReadState, work);
+    vs->err = v9fs_do_lstat(vs->s, &vs->name, &vs->stbuf);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_read_do_seekdir(ThreadletWork *work)
+{
+    V9fsReadState *vs;
+
+    vs = container_of(work, V9fsReadState, work);
+    v9fs_do_seekdir(vs->s, vs->fidp->fs.dir, vs->dir_pos);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+
+
+static void v9fs_read_post_readdir(void *);
+
+static void v9fs_read_post_seekdir(void *opaque)
+{
+    V9fsReadState *vs = (V9fsReadState *)opaque;
+
+    if (vs->err) {
         goto out;
     }
     v9fs_stat_free(&vs->v9stat);
     v9fs_string_free(&vs->name);
     vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->count);
     vs->offset += vs->count;
-    err = vs->offset;
+    vs->err = vs->offset;
 out:
-    complete_pdu(s, vs->pdu, err);
+    complete_pdu(vs->s, vs->pdu, vs->err);
     qemu_free(vs);
     return;
 }
 
-static void v9fs_read_post_dir_lstat(V9fsState *s, V9fsReadState *vs,
-                                    ssize_t err)
+static void v9fs_read_post_dir_lstat(void *opaque)
 {
-    if (err) {
-        err = -errno;
+    V9fsReadState *vs = (V9fsReadState *)opaque;
+
+    if (vs->err) {
+        vs->err = -vs->v9fs_errno;
         goto out;
     }
-    err = stat_to_v9stat(s, &vs->name, &vs->stbuf, &vs->v9stat);
-    if (err) {
+    vs->err = stat_to_v9stat(vs->s, &vs->name, &vs->stbuf, &vs->v9stat);
+    if (vs->err) {
         goto out;
     }
 
@@ -2071,26 +2174,28 @@ static void v9fs_read_post_dir_lstat(V9fsState *s, V9fsReadState *vs,
                             &vs->v9stat);
     if ((vs->len != (vs->v9stat.size + 2)) ||
             ((vs->count + vs->len) > vs->max_count)) {
-        v9fs_do_seekdir(s, vs->fidp->fs.dir, vs->dir_pos);
-        v9fs_read_post_seekdir(s, vs, err);
+        v9fs_do_async_posix(&vs->work, v9fs_read_do_seekdir, &vs->post_fn,
+                            v9fs_read_post_seekdir);
         return;
     }
     vs->count += vs->len;
     v9fs_stat_free(&vs->v9stat);
     v9fs_string_free(&vs->name);
     vs->dir_pos = vs->dent->d_off;
-    vs->dent = v9fs_do_readdir(s, vs->fidp->fs.dir);
-    v9fs_read_post_readdir(s, vs, err);
+    v9fs_do_async_posix(&vs->work, v9fs_read_do_readdir, &vs->post_fn,
+                        v9fs_read_post_readdir);
     return;
 out:
-    v9fs_do_seekdir(s, vs->fidp->fs.dir, vs->dir_pos);
-    v9fs_read_post_seekdir(s, vs, err);
+    v9fs_do_async_posix(&vs->work, v9fs_read_do_seekdir, &vs->post_fn,
+                        v9fs_read_post_seekdir);
     return;
 
 }
 
-static void v9fs_read_post_readdir(V9fsState *s, V9fsReadState *vs, ssize_t err)
+static void v9fs_read_post_readdir(void *opaque)
 {
+    V9fsReadState *vs = (V9fsReadState *)opaque;
+
     if (vs->dent) {
         memset(&vs->v9stat, 0, sizeof(vs->v9stat));
         v9fs_string_init(&vs->name);
@@ -2098,64 +2203,61 @@ static void v9fs_read_post_readdir(V9fsState *s, V9fsReadState *vs, ssize_t err)
                             vs->dent->d_name);
         err = v9fs_do_lstat(s, &vs->name, &vs->stbuf);
         v9fs_read_post_dir_lstat(s, vs, err);
+        v9fs_do_async_posix(&vs->work, v9fs_read_do_lstat, &vs->post_fn,
+                            v9fs_read_post_dir_lstat);
         return;
     }
 
     vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->count);
     vs->offset += vs->count;
-    err = vs->offset;
-    complete_pdu(s, vs->pdu, err);
+    vs->err = vs->offset;
+    complete_pdu(vs->s, vs->pdu, vs->err);
     qemu_free(vs);
     return;
 }
 
-static void v9fs_read_post_telldir(V9fsState *s, V9fsReadState *vs, ssize_t err)
+static void v9fs_read_post_telldir(void *opaque)
 {
-    vs->dent = v9fs_do_readdir(s, vs->fidp->fs.dir);
-    v9fs_read_post_readdir(s, vs, err);
+    V9fsReadState *vs = (V9fsReadState *)opaque;
+
+    v9fs_do_async_posix(&vs->work, v9fs_read_do_readdir, &vs->post_fn,
+                        v9fs_read_post_readdir);
     return;
 }
 
-static void v9fs_read_post_rewinddir(V9fsState *s, V9fsReadState *vs,
-                                       ssize_t err)
+static void v9fs_read_post_rewinddir(void *opaque)
 {
-    vs->dir_pos = v9fs_do_telldir(s, vs->fidp->fs.dir);
-    v9fs_read_post_telldir(s, vs, err);
+    V9fsReadState *vs = (V9fsReadState *)opaque;
+
+    v9fs_do_async_posix(&vs->work, v9fs_read_do_telldir, &vs->post_fn,
+                        v9fs_read_post_telldir);
     return;
 }
 
-static void v9fs_read_post_preadv(V9fsState *s, V9fsReadState *vs, ssize_t err)
+static void v9fs_read_post_preadv(void *opaque)
 {
-    if (err  < 0) {
+    V9fsReadState *vs = (V9fsReadState *)opaque;
+
+    if (vs->err  < 0) {
         /* IO error return the error */
-        err = -errno;
+        vs->err = -errno;
         goto out;
+    } else {
+        vs->off += vs->len;
     }
     vs->total += vs->len;
     vs->sg = adjust_sg(vs->sg, vs->len, &vs->cnt);
     if (vs->total < vs->count && vs->len > 0) {
-        do {
-            if (0) {
-                print_sg(vs->sg, vs->cnt);
-            }
-            vs->len = v9fs_do_preadv(s, vs->fidp->fs.fd, vs->sg, vs->cnt,
-                      vs->off);
-            if (vs->len > 0) {
-                vs->off += vs->len;
-            }
-        } while (vs->len == -1 && errno == EINTR);
-        if (vs->len == -1) {
-            err  = -errno;
-        }
-        v9fs_read_post_preadv(s, vs, err);
+        v9fs_do_async_posix(&vs->work, v9fs_read_do_preadv, &vs->post_fn,
+                            v9fs_read_post_preadv);
         return;
     }
     vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->total);
     vs->offset += vs->count;
-    err = vs->offset;
+    vs->err = vs->offset;
 
 out:
-    complete_pdu(s, vs->pdu, err);
+    complete_pdu(vs->s, vs->pdu, vs->err);
     qemu_free(vs);
 }
 
@@ -2188,7 +2290,6 @@ static void v9fs_read(V9fsState *s, V9fsPDU *pdu)
 {
     int32_t fid;
     V9fsReadState *vs;
-    ssize_t err = 0;
 
     vs = qemu_malloc(sizeof(*vs));
     vs->pdu = pdu;
@@ -2196,12 +2297,13 @@ static void v9fs_read(V9fsState *s, V9fsPDU *pdu)
     vs->total = 0;
     vs->len = 0;
     vs->count = 0;
+    vs->s = s;
 
     pdu_unmarshal(vs->pdu, vs->offset, "dqd", &fid, &vs->off, &vs->count);
 
     vs->fidp = lookup_fid(s, fid);
     if (vs->fidp == NULL) {
-        err = -EINVAL;
+        vs->err = -EINVAL;
         goto out;
     }
 
@@ -2209,32 +2311,30 @@ static void v9fs_read(V9fsState *s, V9fsPDU *pdu)
         vs->max_count = vs->count;
         vs->count = 0;
         if (vs->off == 0) {
-            v9fs_do_rewinddir(s, vs->fidp->fs.dir);
+            v9fs_do_async_posix(&vs->work, v9fs_read_do_rewinddir,
+                                &vs->post_fn, v9fs_read_post_rewinddir);
+            return;
         }
-        v9fs_read_post_rewinddir(s, vs, err);
+        v9fs_read_post_rewinddir(vs);
         return;
     } else if (vs->fidp->fid_type == P9_FID_FILE) {
         vs->sg = vs->iov;
         pdu_marshal(vs->pdu, vs->offset + 4, "v", vs->sg, &vs->cnt);
         vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt);
         if (vs->total <= vs->count) {
-            vs->len = v9fs_do_preadv(s, vs->fidp->fs.fd, vs->sg, vs->cnt,
-                                    vs->off);
-            if (vs->len > 0) {
-                vs->off += vs->len;
-            }
-            err = vs->len;
-            v9fs_read_post_preadv(s, vs, err);
+            vs->err = vs->len;
+            v9fs_do_async_posix(&vs->work, v9fs_read_do_preadv,
+                                &vs->post_fn, v9fs_read_post_preadv);
         }
         return;
     } else if (vs->fidp->fid_type == P9_FID_XATTR) {
         v9fs_xattr_read(s, vs);
         return;
     } else {
-        err = -EINVAL;
+        vs->err = -EINVAL;
     }
 out:
-    complete_pdu(s, pdu, err);
+    complete_pdu(s, pdu, vs->err);
     qemu_free(vs);
 }
 
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index 74d7b68..fcea434 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -325,6 +325,11 @@ typedef struct V9fsReadState {
     int32_t len;
     int32_t cnt;
     int32_t max_count;
+    V9fsState *s;
+    int err;
+    int v9fs_errno;
+    ThreadletWork work;
+    void (*post_fn)(void *arg);
 } V9fsReadState;
 
 typedef struct V9fsWriteState {

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

* [Qemu-devel] [PATCH 4/6] This patch converts v9fs_write() to make use of the threadlets infrastructure.
  2010-10-13 17:20 [Qemu-devel] [RFC PATCH 0/6] First threading model Arun R Bharadwaj
                   ` (2 preceding siblings ...)
  2010-10-13 17:22 ` [Qemu-devel] [PATCH 3/6] This patch converts v9fs_read() " Arun R Bharadwaj
@ 2010-10-13 17:22 ` Arun R Bharadwaj
  2010-10-13 17:23 ` [Qemu-devel] [PATCH 5/6] This patch converts v9fs_open() " Arun R Bharadwaj
  2010-10-13 17:23 ` [Qemu-devel] [PATCH 6/6] This patch converts v9fs_walk() " Arun R Bharadwaj
  5 siblings, 0 replies; 9+ messages in thread
From: Arun R Bharadwaj @ 2010-10-13 17:22 UTC (permalink / raw)
  To: qemu-devel

From: Gautham R Shenoy <ego@in.ibm.com>

This patch offloads all the blocking calls invoked for v9fs_write onto the
helper threads belonging to the threadlets infrastructure. The handling of
the v9fs_post_*write* calls is done from the io-thread context.

Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
Signed-off-by: Arun R Bharadwaj <arun@linux.vnet.ibm.com>
---
 hw/virtio-9p.c |   63 ++++++++++++++++++++++++++++----------------------------
 hw/virtio-9p.h |    5 ++++
 2 files changed, 37 insertions(+), 31 deletions(-)

diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index da185c3..5fb7dc4 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -2459,37 +2459,41 @@ out:
     return;
 }
 
-static void v9fs_write_post_pwritev(V9fsState *s, V9fsWriteState *vs,
-                                   ssize_t err)
+/************************ v9fs_write calls ************************/
+
+static void v9fs_write_do_pwritev(ThreadletWork *work)
+{
+    V9fsWriteState *vs;
+
+    vs = container_of(work, V9fsWriteState, work);
+    v9fs_do_pwritev(vs->s, vs->fidp->fs.fd, vs->sg, vs->cnt, vs->off);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_write_post_pwritev(void *opaque)
 {
-    if (err  < 0) {
+    V9fsWriteState *vs = (V9fsWriteState *)opaque;
+
+    if (vs->err  < 0) {
         /* IO error return the error */
-        err = -errno;
+        vs->err = -errno;
         goto out;
+    } else {
+        vs->off += vs->len;
     }
     vs->total += vs->len;
     vs->sg = adjust_sg(vs->sg, vs->len, &vs->cnt);
     if (vs->total < vs->count && vs->len > 0) {
-        do {
-            if (0) {
-                print_sg(vs->sg, vs->cnt);
-            }
-            vs->len = v9fs_do_pwritev(s, vs->fidp->fs.fd, vs->sg, vs->cnt,
-                      vs->off);
-            if (vs->len > 0) {
-                vs->off += vs->len;
-            }
-        } while (vs->len == -1 && errno == EINTR);
-        if (vs->len == -1) {
-            err  = -errno;
-        }
-        v9fs_write_post_pwritev(s, vs, err);
+        v9fs_do_async_posix(&vs->work, v9fs_write_do_pwritev, &vs->post_fn,
+                            v9fs_write_post_pwritev);
         return;
     }
     vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->total);
-    err = vs->offset;
+    vs->err = vs->offset;
 out:
-    complete_pdu(s, vs->pdu, err);
+    complete_pdu(vs->s, vs->pdu, vs->err);
     qemu_free(vs);
 }
 
@@ -2539,7 +2543,6 @@ static void v9fs_write(V9fsState *s, V9fsPDU *pdu)
 {
     int32_t fid;
     V9fsWriteState *vs;
-    ssize_t err;
 
     vs = qemu_malloc(sizeof(*vs));
 
@@ -2548,19 +2551,20 @@ static void v9fs_write(V9fsState *s, V9fsPDU *pdu)
     vs->sg = vs->iov;
     vs->total = 0;
     vs->len = 0;
+    vs->s = s;
 
     pdu_unmarshal(vs->pdu, vs->offset, "dqdv", &fid, &vs->off, &vs->count,
                   vs->sg, &vs->cnt);
 
     vs->fidp = lookup_fid(s, fid);
     if (vs->fidp == NULL) {
-        err = -EINVAL;
+        vs->err = -EINVAL;
         goto out;
     }
 
     if (vs->fidp->fid_type == P9_FID_FILE) {
         if (vs->fidp->fs.fd == -1) {
-            err = -EINVAL;
+            vs->err = -EINVAL;
             goto out;
         }
     } else if (vs->fidp->fid_type == P9_FID_XATTR) {
@@ -2570,21 +2574,18 @@ static void v9fs_write(V9fsState *s, V9fsPDU *pdu)
         v9fs_xattr_write(s, vs);
         return;
     } else {
-        err = -EINVAL;
+        vs->err = -EINVAL;
         goto out;
     }
     vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt);
     if (vs->total <= vs->count) {
-        vs->len = v9fs_do_pwritev(s, vs->fidp->fs.fd, vs->sg, vs->cnt, vs->off);
-        if (vs->len > 0) {
-            vs->off += vs->len;
-        }
-        err = vs->len;
-        v9fs_write_post_pwritev(s, vs, err);
+        vs->err = vs->len;
+        v9fs_do_async_posix(&vs->work, v9fs_write_do_pwritev, &vs->post_fn,
+                            v9fs_write_post_pwritev);
     }
     return;
 out:
-    complete_pdu(s, vs->pdu, err);
+    complete_pdu(vs->s, vs->pdu, vs->err);
     qemu_free(vs);
 }
 
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index fcea434..be87d5f 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -343,6 +343,11 @@ typedef struct V9fsWriteState {
     struct iovec iov[128]; /* FIXME: bad, bad, bad */
     struct iovec *sg;
     int cnt;
+    V9fsState *s;
+    int err;
+    int v9fs_errno;
+    ThreadletWork work;
+    void (*post_fn)(void *arg);
 } V9fsWriteState;
 
 typedef struct V9fsRemoveState {

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

* [Qemu-devel] [PATCH 5/6] This patch converts v9fs_open() to make use of the threadlets infrastructure.
  2010-10-13 17:20 [Qemu-devel] [RFC PATCH 0/6] First threading model Arun R Bharadwaj
                   ` (3 preceding siblings ...)
  2010-10-13 17:22 ` [Qemu-devel] [PATCH 4/6] This patch converts v9fs_write() " Arun R Bharadwaj
@ 2010-10-13 17:23 ` Arun R Bharadwaj
  2010-10-13 17:23 ` [Qemu-devel] [PATCH 6/6] This patch converts v9fs_walk() " Arun R Bharadwaj
  5 siblings, 0 replies; 9+ messages in thread
From: Arun R Bharadwaj @ 2010-10-13 17:23 UTC (permalink / raw)
  To: qemu-devel

From: Gautham R Shenoy <ego@in.ibm.com>

This patch offloads all the blocking calls invoked for v9fs_open onto the
helper threads belonging to the threadlets infrastructure. The handling of
the v9fs_post_*open* calls is done from the io-thread context.

Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
---
 hw/virtio-9p.c |   86 +++++++++++++++++++++++++++++++++++++++++---------------
 hw/virtio-9p.h |    5 +++
 2 files changed, 68 insertions(+), 23 deletions(-)

diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 5fb7dc4..75d4be3 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -1777,6 +1777,41 @@ out:
     v9fs_walk_complete(s, vs, err);
 }
 
+/********************* v9fs_open calls *********************************/
+static void v9fs_open_do_lstat(ThreadletWork *work)
+{
+    V9fsOpenState *vs;
+
+    vs = container_of(work, V9fsOpenState, work);
+    vs->err = v9fs_do_lstat(vs->s, &vs->fidp->path, &vs->stbuf);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_open_do_opendir(ThreadletWork *work)
+{
+    V9fsOpenState *vs;
+
+    vs = container_of(work, V9fsOpenState, work);
+    vs->fidp->fs.dir = v9fs_do_opendir(vs->s, &vs->fidp->path);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_open_do_open(ThreadletWork *work)
+{
+    V9fsOpenState *vs;
+
+    vs = container_of(work, V9fsOpenState, work);
+    vs->fidp->fs.fd = v9fs_do_open(vs->s, &vs->fidp->path,
+                                omode_to_uflags(vs->mode));
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
 static int32_t get_iounit(V9fsState *s, V9fsString *name)
 {
     struct statfs stbuf;
@@ -1797,17 +1832,19 @@ static int32_t get_iounit(V9fsState *s, V9fsString *name)
     return iounit;
 }
 
-static void v9fs_open_post_opendir(V9fsState *s, V9fsOpenState *vs, int err)
+static void v9fs_open_post_opendir(void *opaque)
 {
+    V9fsOpenState *vs = (V9fsOpenState *)opaque;
+
     if (vs->fidp->fs.dir == NULL) {
-        err = -errno;
+        vs->err = -errno;
         goto out;
     }
     vs->fidp->fid_type = P9_FID_DIR;
     vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, 0);
-    err = vs->offset;
+    vs->err = vs->offset;
 out:
-    complete_pdu(s, vs->pdu, err);
+    complete_pdu(vs->s, vs->pdu, vs->err);
     qemu_free(vs);
 
 }
@@ -1821,35 +1858,39 @@ static void v9fs_open_post_getiounit(V9fsState *s, V9fsOpenState *vs)
     qemu_free(vs);
 }
 
-static void v9fs_open_post_open(V9fsState *s, V9fsOpenState *vs, int err)
+static void v9fs_open_post_open(void *opaque)
 {
+    V9fsOpenState *vs = (V9fsOpenState *)opaque;
+
     if (vs->fidp->fs.fd == -1) {
-        err = -errno;
+        vs->err = -errno;
         goto out;
     }
     vs->fidp->fid_type = P9_FID_FILE;
-    vs->iounit = get_iounit(s, &vs->fidp->path);
-    v9fs_open_post_getiounit(s, vs);
+    /* FIXME: Need a new state here */
+    vs->iounit = get_iounit(vs->s, &vs->fidp->path);
+    v9fs_open_post_getiounit(vs->s, vs);
     return;
 out:
-    complete_pdu(s, vs->pdu, err);
+    complete_pdu(vs->s, vs->pdu, vs->err);
     qemu_free(vs);
 }
 
-static void v9fs_open_post_lstat(V9fsState *s, V9fsOpenState *vs, int err)
+static void v9fs_open_post_lstat(void *opaque)
 {
+    V9fsOpenState *vs = (V9fsOpenState *)opaque;
     int flags;
 
-    if (err) {
-        err = -errno;
+    if (vs->err) {
+        vs->err = -errno;
         goto out;
     }
 
     stat_to_qid(&vs->stbuf, &vs->qid);
 
     if (S_ISDIR(vs->stbuf.st_mode)) {
-        vs->fidp->fs.dir = v9fs_do_opendir(s, &vs->fidp->path);
-        v9fs_open_post_opendir(s, vs, err);
+        v9fs_do_async_posix(&vs->work, v9fs_open_do_opendir, &vs->post_fn,
+                            v9fs_open_post_opendir);
     } else {
         if (s->proto_version == V9FS_PROTO_2000L) {
             flags = vs->mode;
@@ -1859,12 +1900,12 @@ static void v9fs_open_post_lstat(V9fsState *s, V9fsOpenState *vs, int err)
         } else {
             flags = omode_to_uflags(vs->mode);
         }
-        vs->fidp->fs.fd = v9fs_do_open(s, &vs->fidp->path, flags);
-        v9fs_open_post_open(s, vs, err);
+        v9fs_do_async_posix(&vs->work, v9fs_open_do_open, &vs->post_fn,
+                             v9fs_open_post_open);
     }
     return;
 out:
-    complete_pdu(s, vs->pdu, err);
+    complete_pdu(vs->s, vs->pdu, vs->err);
     qemu_free(vs);
 }
 
@@ -1872,12 +1913,12 @@ static void v9fs_open(V9fsState *s, V9fsPDU *pdu)
 {
     int32_t fid;
     V9fsOpenState *vs;
-    ssize_t err = 0;
 
     vs = qemu_malloc(sizeof(*vs));
     vs->pdu = pdu;
     vs->offset = 7;
     vs->mode = 0;
+    vs->s = s;
 
     if (s->proto_version == V9FS_PROTO_2000L) {
         pdu_unmarshal(vs->pdu, vs->offset, "dd", &fid, &vs->mode);
@@ -1887,18 +1928,17 @@ static void v9fs_open(V9fsState *s, V9fsPDU *pdu)
 
     vs->fidp = lookup_fid(s, fid);
     if (vs->fidp == NULL) {
-        err = -ENOENT;
+        vs->err = -ENOENT;
         goto out;
     }
 
     BUG_ON(vs->fidp->fid_type != P9_FID_NONE);
 
-    err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
-
-    v9fs_open_post_lstat(s, vs, err);
+    v9fs_do_async_posix(&vs->work, v9fs_open_do_lstat, &vs->post_fn,
+                        v9fs_open_post_lstat);
     return;
 out:
-    complete_pdu(s, pdu, err);
+    complete_pdu(vs->s, pdu, vs->err);
     qemu_free(vs);
 }
 
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index be87d5f..294de83 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -306,6 +306,11 @@ typedef struct V9fsOpenState {
     V9fsQID qid;
     struct stat stbuf;
     int iounit;
+    V9fsState *s;
+    int err;
+    int v9fs_errno;
+    ThreadletWork work;
+    void (*post_fn)(void *arg);
 } V9fsOpenState;
 
 typedef struct V9fsReadState {

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

* [Qemu-devel] [PATCH 6/6] This patch converts v9fs_walk() to make use of the threadlets infrastructure.
  2010-10-13 17:20 [Qemu-devel] [RFC PATCH 0/6] First threading model Arun R Bharadwaj
                   ` (4 preceding siblings ...)
  2010-10-13 17:23 ` [Qemu-devel] [PATCH 5/6] This patch converts v9fs_open() " Arun R Bharadwaj
@ 2010-10-13 17:23 ` Arun R Bharadwaj
  5 siblings, 0 replies; 9+ messages in thread
From: Arun R Bharadwaj @ 2010-10-13 17:23 UTC (permalink / raw)
  To: qemu-devel

From: Gautham R Shenoy <ego@in.ibm.com>

This patch offloads all the blocking calls invoked for v9fs_walk onto the
helper threads belonging to the threadlets infrastructure. The handling of
the v9fs_post_*walk* calls is done from the io-thread context.

Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
---
 hw/virtio-9p.c |   78 +++++++++++++++++++++++++++++++++++++-------------------
 hw/virtio-9p.h |    5 ++++
 2 files changed, 57 insertions(+), 26 deletions(-)

diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 75d4be3..e95bf50 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -1615,6 +1615,29 @@ out:
     qemu_free(vs);
 }
 
+/************************* v9fs_walk calls *****************************/
+static void v9fs_walk_do_lstat_old(ThreadletWork *work)
+{
+    V9fsWalkState *vs;
+
+    vs = container_of(work, V9fsWalkState, work);
+    vs->err = v9fs_do_lstat(vs->s, &vs->fidp->path, &vs->stbuf);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_walk_do_lstat_new(ThreadletWork *work)
+{
+    V9fsWalkState *vs;
+
+    vs = container_of(work, V9fsWalkState, work);
+    vs->err = v9fs_do_lstat(vs->s, &vs->newfidp->path, &vs->stbuf);
+    vs->v9fs_errno = errno;
+
+    v9fs_async_helper_done(vs->post_fn, vs);
+}
+
 static void v9fs_walk_complete(V9fsState *s, V9fsWalkState *vs, int err)
 {
     complete_pdu(s, vs->pdu, err);
@@ -1640,13 +1663,14 @@ static void v9fs_walk_marshal(V9fsWalkState *vs)
     }
 }
 
-static void v9fs_walk_post_newfid_lstat(V9fsState *s, V9fsWalkState *vs,
-                                                                int err)
+static void v9fs_walk_post_newfid_lstat(void *opaque)
 {
-    if (err == -1) {
-        free_fid(s, vs->newfidp->fid);
+    V9fsWalkState *vs = (V9fsWalkState *)opaque;
+
+    if (vs->err == -1) {
+        free_fid(vs->s, vs->newfidp->fid);
         v9fs_string_free(&vs->path);
-        err = -ENOENT;
+        vs->err = -ENOENT;
         goto out;
     }
 
@@ -1658,24 +1682,25 @@ static void v9fs_walk_post_newfid_lstat(V9fsState *s, V9fsWalkState *vs,
                                             vs->wnames[vs->name_idx].data);
         v9fs_string_copy(&vs->newfidp->path, &vs->path);
 
-        err = v9fs_do_lstat(s, &vs->newfidp->path, &vs->stbuf);
-        v9fs_walk_post_newfid_lstat(s, vs, err);
+        v9fs_do_async_posix(&vs->work, v9fs_walk_do_lstat_new, &vs->post_fn,
+                            v9fs_walk_post_newfid_lstat);
         return;
     }
 
     v9fs_string_free(&vs->path);
     v9fs_walk_marshal(vs);
-    err = vs->offset;
+    vs->err = vs->offset;
 out:
-    v9fs_walk_complete(s, vs, err);
+    v9fs_walk_complete(vs->s, vs, vs->err);
 }
 
-static void v9fs_walk_post_oldfid_lstat(V9fsState *s, V9fsWalkState *vs,
-        int err)
+static void v9fs_walk_post_oldfid_lstat(void *opaque)
 {
-    if (err == -1) {
+    V9fsWalkState *vs = (V9fsWalkState *)opaque;
+
+    if (vs->err == -1) {
         v9fs_string_free(&vs->path);
-        err = -ENOENT;
+        vs->err = -ENOENT;
         goto out;
     }
 
@@ -1687,23 +1712,22 @@ static void v9fs_walk_post_oldfid_lstat(V9fsState *s, V9fsWalkState *vs,
                 vs->fidp->path.data, vs->wnames[vs->name_idx].data);
         v9fs_string_copy(&vs->fidp->path, &vs->path);
 
-        err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
-        v9fs_walk_post_oldfid_lstat(s, vs, err);
+        v9fs_do_async_posix(&vs->work, v9fs_walk_do_lstat_old, &vs->post_fn,
+                            v9fs_walk_post_oldfid_lstat);
         return;
     }
 
     v9fs_string_free(&vs->path);
     v9fs_walk_marshal(vs);
-    err = vs->offset;
+    vs->err = vs->offset;
 out:
-    v9fs_walk_complete(s, vs, err);
+    v9fs_walk_complete(vs->s, vs, vs->err);
 }
 
 static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
 {
     int32_t fid, newfid;
     V9fsWalkState *vs;
-    int err = 0;
     int i;
 
     vs = qemu_malloc(sizeof(*vs));
@@ -1711,6 +1735,8 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
     vs->wnames = NULL;
     vs->qids = NULL;
     vs->offset = 7;
+    vs->err = 0;
+    vs->s = s;
 
     vs->offset += pdu_unmarshal(vs->pdu, vs->offset, "ddw", &fid,
                                             &newfid, &vs->nwnames);
@@ -1728,7 +1754,7 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
 
     vs->fidp = lookup_fid(s, fid);
     if (vs->fidp == NULL) {
-        err = -ENOENT;
+        vs->err = -ENOENT;
         goto out;
     }
 
@@ -1744,14 +1770,14 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
                 vs->fidp->path.data, vs->wnames[vs->name_idx].data);
             v9fs_string_copy(&vs->fidp->path, &vs->path);
 
-            err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
-            v9fs_walk_post_oldfid_lstat(s, vs, err);
+            v9fs_do_async_posix(&vs->work, v9fs_walk_do_lstat_old,
+                                &vs->post_fn, v9fs_walk_post_oldfid_lstat);
             return;
         }
     } else {
         vs->newfidp = alloc_fid(s, newfid);
         if (vs->newfidp == NULL) {
-            err = -EINVAL;
+            vs->err = -EINVAL;
             goto out;
         }
 
@@ -1765,16 +1791,16 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
                                 vs->wnames[vs->name_idx].data);
             v9fs_string_copy(&vs->newfidp->path, &vs->path);
 
-            err = v9fs_do_lstat(s, &vs->newfidp->path, &vs->stbuf);
-            v9fs_walk_post_newfid_lstat(s, vs, err);
+            v9fs_do_async_posix(&vs->work, v9fs_walk_do_lstat_new,
+                                &vs->post_fn, v9fs_walk_post_newfid_lstat);
             return;
         }
     }
 
     v9fs_walk_marshal(vs);
-    err = vs->offset;
+    vs->err = vs->offset;
 out:
-    v9fs_walk_complete(s, vs, err);
+    v9fs_walk_complete(s, vs, vs->err);
 }
 
 /********************* v9fs_open calls *********************************/
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index 294de83..f88b5fc 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -296,6 +296,11 @@ typedef struct V9fsWalkState {
     V9fsString path;
     V9fsString *wnames;
     struct stat stbuf;
+    V9fsState *s;
+    int err;
+    int v9fs_errno;
+    ThreadletWork work;
+    void (*post_fn)(void *arg);
 } V9fsWalkState;
 
 typedef struct V9fsOpenState {

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

end of thread, other threads:[~2010-10-13 17:23 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-13 17:20 [Qemu-devel] [RFC PATCH 0/6] First threading model Arun R Bharadwaj
2010-10-13 17:21 ` [Qemu-devel] [PATCH 1/6] This patch converts v9fs_stat() to make use of the threadlets infrastructure Arun R Bharadwaj
2010-10-13 17:21 ` [Qemu-devel] [PATCH 2/6] This patch converts v9fs_wstat() " Arun R Bharadwaj
2010-10-13 17:22 ` [Qemu-devel] [PATCH 3/6] This patch converts v9fs_read() " Arun R Bharadwaj
2010-10-13 17:22 ` [Qemu-devel] [PATCH 4/6] This patch converts v9fs_write() " Arun R Bharadwaj
2010-10-13 17:23 ` [Qemu-devel] [PATCH 5/6] This patch converts v9fs_open() " Arun R Bharadwaj
2010-10-13 17:23 ` [Qemu-devel] [PATCH 6/6] This patch converts v9fs_walk() " Arun R Bharadwaj
  -- strict thread matches above, loose matches on Subject: below --
2010-10-13 17:09 [Qemu-devel] [RFC PATCH 0/6] First Threading Model Arun R Bharadwaj
2010-10-13 17:10 ` [Qemu-devel] [PATCH 6/6] This patch converts v9fs_walk() to make use of the threadlets infrastructure Arun R Bharadwaj
2010-10-13 15:36 [Qemu-devel] [PATCH 0/6] First threading model Arun R Bharadwaj
2010-10-13 15:38 ` [Qemu-devel] [PATCH 6/6] This patch converts v9fs_walk() to make use of the threadlets infrastructure Arun R Bharadwaj

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