[sheepdog] [PATCH 1/2] sheep: use work queue for asynchronous local request

MORITA Kazutaka morita.kazutaka at gmail.com
Fri Jan 17 04:35:31 CET 2014


From: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>

We can use our work queue framework for handling asynchrouns requests.
There is no need to create short living events.

Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 sheep/request.c    | 73 +++++++++++++++++++++++++++++-------------------------
 sheep/sheep.c      |  4 ++-
 sheep/sheep_priv.h |  2 +-
 3 files changed, 43 insertions(+), 36 deletions(-)

diff --git a/sheep/request.c b/sheep/request.c
index 161b7db..a15fd8c 100644
--- a/sheep/request.c
+++ b/sheep/request.c
@@ -575,31 +575,11 @@ out:
 	return ret;
 }
 
-static void local_req_async_handler(int fd, int events, void *data)
-{
-	struct request *req = data;
-	struct request_iocb *iocb = req->iocb;
-
-	if (events & EPOLLERR)
-		sd_err("request handler error");
-	eventfd_xread(fd);
-
-	if (unlikely(req->rp.result != SD_RES_SUCCESS))
-		iocb->result = req->rp.result;
-
-	if (uatomic_sub_return(&iocb->count, 1) == 0)
-		eventfd_xwrite(iocb->efd, 1);
-
-	unregister_event(req->local_req_efd);
-	close(req->local_req_efd);
-	free_local_request(req);
-}
-
 worker_fn struct request_iocb *local_req_init(void)
 {
 	struct request_iocb *iocb = xzalloc(sizeof(*iocb));
 
-	iocb->efd = eventfd(0, 0);
+	iocb->efd = eventfd(0, EFD_SEMAPHORE);
 	if (iocb->efd < 0) {
 		sd_err("eventfd failed, %m");
 		free(iocb);
@@ -613,7 +593,8 @@ worker_fn int local_req_wait(struct request_iocb *iocb)
 {
 	int ret;
 
-	eventfd_xread(iocb->efd);
+	for (int i = 0; i < iocb->count; i++)
+		eventfd_xread(iocb->efd);
 
 	ret = iocb->result;
 	close(iocb->efd);
@@ -621,23 +602,47 @@ worker_fn int local_req_wait(struct request_iocb *iocb)
 	return ret;
 }
 
+struct areq_work {
+	struct sd_req rq;
+	void *data;
+	struct request_iocb *iocb;
+	int result;
+
+	struct work work;
+};
+
+static void local_req_async_work(struct work *work)
+{
+	struct areq_work *areq = container_of(work, struct areq_work, work);
+
+	areq->result = exec_local_req(&areq->rq, areq->data);
+}
+
+static void local_req_async_main(struct work *work)
+{
+	struct areq_work *areq = container_of(work, struct areq_work, work);
+
+	if (unlikely(areq->result != SD_RES_SUCCESS))
+		areq->iocb->result = areq->result;
+
+	eventfd_xwrite(areq->iocb->efd, 1);
+}
+
 worker_fn int exec_local_req_async(struct sd_req *rq, void *data,
 				   struct request_iocb *iocb)
 {
-	struct request *req;
+	struct areq_work *areq;
 
-	req = alloc_local_request(data, rq->data_length);
-	req->rq = *rq;
-	req->local_req_efd = eventfd(0, EFD_NONBLOCK);
-	if (req->local_req_efd < 0) {
-		sd_err("eventfd failed, %m");
-		return SD_RES_SYSTEM_ERROR;
-	}
+	areq = xzalloc(sizeof(*areq));
+	areq->rq = *rq;
+	areq->data = data;
+	areq->iocb = iocb;
+	areq->work.fn = local_req_async_work;
+	areq->work.done = local_req_async_main;
 
-	uatomic_inc(&iocb->count);
-	req->iocb = iocb;
-	register_event(req->local_req_efd, local_req_async_handler, req);
-	submit_local_request(req);
+	queue_work(sys->areq_wqueue, &areq->work);
+
+	iocb->count++;
 
 	return SD_RES_SUCCESS;
 }
diff --git a/sheep/sheep.c b/sheep/sheep.c
index a550f22..c6733b9 100644
--- a/sheep/sheep.c
+++ b/sheep/sheep.c
@@ -436,6 +436,7 @@ static int create_work_queues(void)
 	sys->deletion_wqueue = create_ordered_work_queue("deletion");
 	sys->block_wqueue = create_ordered_work_queue("block");
 	sys->md_wqueue = create_ordered_work_queue("md");
+	sys->areq_wqueue = create_work_queue("async_req", WQ_UNLIMITED);
 	if (sys->enable_object_cache) {
 		sys->oc_reclaim_wqueue =
 			create_ordered_work_queue("oc_reclaim");
@@ -444,7 +445,8 @@ static int create_work_queues(void)
 			return -1;
 	}
 	if (!sys->gateway_wqueue || !sys->io_wqueue || !sys->recovery_wqueue ||
-	    !sys->deletion_wqueue || !sys->block_wqueue || !sys->md_wqueue)
+	    !sys->deletion_wqueue || !sys->block_wqueue || !sys->md_wqueue ||
+	    !sys->areq_wqueue)
 			return -1;
 
 	return 0;
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index c0a138c..e8d688b 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -106,7 +106,6 @@ struct request {
 	refcnt_t refcnt;
 	bool local;
 	int local_req_efd;
-	struct request_iocb *iocb;
 
 	uint64_t local_oid;
 
@@ -149,6 +148,7 @@ struct system_info {
 	struct work_queue *oc_reclaim_wqueue;
 	struct work_queue *oc_push_wqueue;
 	struct work_queue *md_wqueue;
+	struct work_queue *areq_wqueue;
 #ifdef HAVE_HTTP
 	struct work_queue *http_wqueue;
 #endif
-- 
1.8.1.2




More information about the sheepdog mailing list