mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Dominique Martinet <asmadeus@codewreck.org>
To: v9fs-developer@lists.sourceforge.net,
	Eric Van Hensbergen <ericvh@gmail.com>,
	Christian Schoenebeck <linux_oss@crudebyte.com>
Cc: Latchesar Ionkov <lucho@ionkov.net>,
	linux-kernel@vger.kernel.org, Jens Axboe <axboe@kernel.dk>,
	Pengfei Xu <pengfei.xu@intel.com>,
	Dominique Martinet <asmadeus@codewreck.org>
Subject: [PATCH 3/5] 9p/net: implement asynchronous rpc skeleton
Date: Sat, 11 Feb 2023 16:50:21 +0900	[thread overview]
Message-ID: <20230211075023.137253-4-asmadeus@codewreck.org> (raw)
In-Reply-To: <20230211075023.137253-1-asmadeus@codewreck.org>

Add p9_client_async_rpc that will let us send an rpc without waiting
for the reply, as well as an async callback hook.

The callback is called, but nothing is ever put in the list at this
point and p9_client_async_rpc() is unused.

Previous version of this patch here[1] used to implement the async check
separately from the callback, but we will want to be notified when flush
has been processed.

Link: http://lkml.kernel.org/r/1544532108-21689-1-git-send-email-asmadeus@codewreck.org (v1)
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
---
 include/net/9p/client.h |  9 ++++-
 net/9p/client.c         | 76 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 84 insertions(+), 1 deletion(-)

diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index 78ebcf782ce5..348ea191ac66 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -72,7 +72,8 @@ enum p9_req_status_t {
  * @wq: wait_queue for the client to block on for this request
  * @tc: the request fcall structure
  * @rc: the response fcall structure
- * @req_list: link for higher level objects to chain requests
+ * @req_list: link for transports to chain requests (used by trans_fd)
+ * @async_list: link used to check on async requests
  */
 struct p9_req_t {
 	int status;
@@ -82,6 +83,7 @@ struct p9_req_t {
 	struct p9_fcall tc;
 	struct p9_fcall rc;
 	struct list_head req_list;
+	struct list_head async_list;
 };
 
 /**
@@ -92,6 +94,9 @@ struct p9_req_t {
  * @trans_mod: module API instantiated with this client
  * @status: connection state
  * @trans: tranport instance state and API
+ * @fcall_cache: kmem cache for client request data (msize-specific)
+ * @async_req_lock: protects @async_req_list
+ * @async_req_list: list of requests waiting a reply
  * @fids: All active FID handles
  * @reqs: All active requests.
  * @name: node name used as client id
@@ -107,6 +112,8 @@ struct p9_client {
 	enum p9_trans_status status;
 	void *trans;
 	struct kmem_cache *fcall_cache;
+	spinlock_t async_req_lock;
+	struct list_head async_req_list;
 
 	union {
 		struct {
diff --git a/net/9p/client.c b/net/9p/client.c
index 4e5238db4a7a..3235543c1884 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -311,6 +311,7 @@ p9_tag_alloc(struct p9_client *c, int8_t type, uint t_size, uint r_size,
 	refcount_set(&req->refcount, 0);
 	init_waitqueue_head(&req->wq);
 	INIT_LIST_HEAD(&req->req_list);
+	INIT_LIST_HEAD(&req->async_list);
 
 	idr_preload(GFP_NOFS);
 	spin_lock_irq(&c->lock);
@@ -495,6 +496,27 @@ void do_trace_9p_fid_put(struct p9_fid *fid)
 }
 EXPORT_SYMBOL(do_trace_9p_fid_put);
 
+/**
+ * p9_client_async_cb -- handle async requests in cb
+ * @c: client state
+ * @req: request received
+ */
+static void p9_client_async_cb(struct p9_client *c, struct p9_req_t *req)
+{
+	unsigned long flags;
+
+	/* Nothing to do for non-async requests */
+	if (likely(list_empty(&req->async_list)))
+		return;
+
+	WARN(1, "Async request received with tc.id %d\n", req->tc.id);
+
+	spin_lock_irqsave(&c->async_req_lock, flags);
+	list_del(&req->async_list);
+	spin_unlock_irqrestore(&c->async_req_lock, flags);
+	p9_tag_remove(c, req);
+}
+
 /**
  * p9_client_cb - call back from transport to client
  * @c: client state
@@ -506,6 +528,8 @@ void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status)
 {
 	p9_debug(P9_DEBUG_MUX, " tag %d\n", req->tc.tag);
 
+	p9_client_async_cb(c, req);
+
 	/* This barrier is needed to make sure any change made to req before
 	 * the status change is visible to another thread
 	 */
@@ -676,6 +700,54 @@ static struct p9_req_t *p9_client_prepare_req(struct p9_client *c,
 	return ERR_PTR(err);
 }
 
+static struct p9_req_t *
+p9_client_async_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
+{
+	va_list ap;
+	int err;
+	struct p9_req_t *req;
+
+	va_start(ap, fmt);
+	/* auto determine an appropriate request/response size */
+	req = p9_client_prepare_req(c, type, 0, 0, fmt, ap);
+	va_end(ap);
+	if (IS_ERR(req))
+		return req;
+
+	err = c->trans_mod->request(c, req);
+	if (err < 0) {
+		/* bail out without flushing... */
+		p9_req_put(c, req);
+		p9_tag_remove(c, req);
+		if (err != -ERESTARTSYS && err != -EFAULT)
+			c->status = Disconnected;
+		return ERR_PTR(safe_errno(err));
+	}
+
+	return req;
+}
+
+static void p9_client_cleanup_async(struct p9_client *c)
+{
+	struct p9_req_t *req, *nreq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&c->async_req_lock, flags);
+	list_for_each_entry_safe(req, nreq, &c->async_req_list, async_list) {
+		if (req->status < REQ_STATUS_RCVD) {
+			p9_debug(P9_DEBUG_ERROR,
+				 "final async handler found req tag %d type %d status %d\n",
+				 req->tc.tag, req->tc.id, req->status);
+			if (c->trans_mod->cancelled)
+				c->trans_mod->cancelled(c, req);
+			/* won't receive reply now */
+			p9_req_put(c, req);
+		}
+		p9_client_async_cb(c, req);
+	}
+	spin_unlock_irqrestore(&c->async_req_lock, flags);
+}
+
 static struct p9_req_t *
 p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...);
 
@@ -983,6 +1055,8 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
 	memcpy(clnt->name, client_id, strlen(client_id) + 1);
 
 	spin_lock_init(&clnt->lock);
+	spin_lock_init(&clnt->async_req_lock);
+	INIT_LIST_HEAD(&clnt->async_req_list);
 	idr_init(&clnt->fids);
 	idr_init(&clnt->reqs);
 
@@ -1059,6 +1133,8 @@ void p9_client_destroy(struct p9_client *clnt)
 
 	v9fs_put_trans(clnt->trans_mod);
 
+	p9_client_cleanup_async(clnt);
+
 	idr_for_each_entry(&clnt->fids, fid, id) {
 		pr_info("Found fid %d not clunked\n", fid->fid);
 		p9_fid_destroy(fid);
-- 
2.39.1


  parent reply	other threads:[~2023-02-11  7:51 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-11  7:50 [PATCH 0/5] Take 3 at async RPCs and no longer looping forever on signals Dominique Martinet
2023-02-11  7:50 ` [PATCH 1/5] 9p/net: move code in preparation of async rpc Dominique Martinet
2023-02-13 17:46   ` Christian Schoenebeck
2023-02-11  7:50 ` [PATCH 2/5] 9p/net: share pooled receive buffers size exception in p9_tag_alloc Dominique Martinet
2023-02-13 18:06   ` Christian Schoenebeck
2023-02-11  7:50 ` Dominique Martinet [this message]
2023-02-11  7:50 ` [PATCH 4/5] 9p/net: add async clunk for retries Dominique Martinet
2023-02-11  7:50 ` [PATCH 5/5] 9p/net: make flush asynchronous Dominique Martinet
2023-02-11  8:05 ` [PATCH 0/5] Take 3 at async RPCs and no longer looping forever on signals Dominique Martinet
2023-02-13 18:26 ` Christian Schoenebeck
2023-02-13 18:45   ` Christian Schoenebeck
2023-02-13 22:37     ` Dominique Martinet
2023-02-14  9:34       ` Christian Schoenebeck
2023-02-14 11:16         ` Dominique Martinet
2023-03-19 11:53           ` [V9fs-developer] " Dominique Martinet
2023-03-23 15:58             ` Christian Schoenebeck
2023-03-25 12:45               ` 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=20230211075023.137253-4-asmadeus@codewreck.org \
    --to=asmadeus@codewreck.org \
    --cc=axboe@kernel.dk \
    --cc=ericvh@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux_oss@crudebyte.com \
    --cc=lucho@ionkov.net \
    --cc=pengfei.xu@intel.com \
    --cc=v9fs-developer@lists.sourceforge.net \
    /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

Powered by JetHome