[Stgt-devel] [PATCH 02/20] iser counter events

Pete Wyckoff pw
Tue Oct 16 17:18:57 CEST 2007


Like fd event handling, also handle integer counter events.  This will
be used in RDMA to make progress on a connection, necessary because
RDMA API does not have a file descriptor that can be used with poll
to detect connection writability.

Signed-off-by: Pete Wyckoff <pw at osc.edu>
---
 usr/tgtd.c |   70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 usr/tgtd.h |    4 +++
 2 files changed, 70 insertions(+), 4 deletions(-)

diff --git a/usr/tgtd.c b/usr/tgtd.c
index 42e21f4..6744534 100644
--- a/usr/tgtd.c
+++ b/usr/tgtd.c
@@ -41,9 +41,15 @@
 #define MAX_FDS	4096
 
 struct tgt_event {
-	event_handler_t *handler;
+	union {
+		event_handler_t *handler;
+		counter_event_handler_t *counter_handler;
+	};
+	union {
+		int fd;
+		int *counter;
+	};
 	void *data;
-	int fd;
 	struct list_head e_list;
 };
 
@@ -52,6 +58,7 @@ unsigned long pagesize, pageshift, pagemask;
 static int ep_fd;
 static char program_name[] = "tgtd";
 static LIST_HEAD(tgt_events_list);
+static LIST_HEAD(tgt_counter_events_list);
 
 static struct option const long_options[] =
 {
@@ -129,6 +136,22 @@ int tgt_event_add(int fd, int events, event_handler_t handler, void *data)
 	return err;
 }
 
+int tgt_counter_event_add(int *counter, counter_event_handler_t handler,
+			  void *data)
+{
+	struct tgt_event *tev;
+
+	tev = zalloc(sizeof(*tev));
+	if (!tev)
+		return -ENOMEM;
+
+	tev->data = data;
+	tev->counter_handler = handler;
+	tev->counter = counter;
+	list_add(&tev->e_list, &tgt_counter_events_list);
+	return 0;
+}
+
 static struct tgt_event *tgt_event_lookup(int fd)
 {
 	struct tgt_event *tev;
@@ -140,6 +163,17 @@ static struct tgt_event *tgt_event_lookup(int fd)
 	return NULL;
 }
 
+static struct tgt_event *tgt_counter_event_lookup(int *counter)
+{
+	struct tgt_event *tev;
+
+	list_for_each_entry(tev, &tgt_counter_events_list, e_list) {
+		if (tev->counter == counter)
+			return tev;
+	}
+	return NULL;
+}
+
 void tgt_event_del(int fd)
 {
 	struct tgt_event *tev;
@@ -155,6 +189,20 @@ void tgt_event_del(int fd)
 	free(tev);
 }
 
+void tgt_counter_event_del(int *counter)
+{
+	struct tgt_event *tev;
+
+	tev = tgt_counter_event_lookup(counter);
+	if (!tev) {
+		eprintf("Cannot find counter event %p\n", counter);
+		return;
+	}
+
+	list_del(&tev->e_list);
+	free(tev);
+}
+
 int tgt_event_modify(int fd, int events)
 {
 	struct epoll_event ev;
@@ -174,11 +222,25 @@ int tgt_event_modify(int fd, int events)
 
 static void event_loop(void)
 {
-	int nevent, i, timeout = TGTD_TICK_PERIOD * 1000;
+	int nevent, i, done, timeout = TGTD_TICK_PERIOD * 1000;
 	struct epoll_event events[1024];
-	struct tgt_event *tev;
+	struct tgt_event *tev, *tevn;
 
 retry:
+	/*
+	 * Check the counter events to see if they have any work to run.
+	 */
+	do {
+		done = 1;
+		list_for_each_entry_safe(tev, tevn, &tgt_counter_events_list,
+					e_list) {
+			if (*tev->counter) {
+				done = 0;
+				tev->counter_handler(tev->counter, tev->data);
+			}
+		}
+	} while (!done);
+
 	nevent = epoll_wait(ep_fd, events, ARRAY_SIZE(events), timeout);
 	if (nevent < 0) {
 		if (errno != EINTR) {
diff --git a/usr/tgtd.h b/usr/tgtd.h
index 8d5b2b6..1f8e33b 100644
--- a/usr/tgtd.h
+++ b/usr/tgtd.h
@@ -209,8 +209,12 @@ extern int tgt_unbind_host_to_target(int tid, int host_no);
 extern int tgt_bound_target_lookup(int host_no);
 
 typedef void (event_handler_t)(int fd, int events, void *data);
+typedef void (counter_event_handler_t)(int *counter, void *data);
 extern int tgt_event_add(int fd, int events, event_handler_t handler, void *data);
+extern int tgt_counter_event_add(int *counter, counter_event_handler_t handler,
+				 void *data);
 extern void tgt_event_del(int fd);
+extern void tgt_counter_event_del(int *counter);
 extern int tgt_event_modify(int fd, int events);
 extern int target_cmd_queue(int tid, struct scsi_cmd *cmd);
 extern void target_cmd_done(struct scsi_cmd *cmd);
-- 
1.5.3.4




More information about the stgt mailing list