Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Aug 2007 16:18:50 GMT
From:      Maxim Zhuravlev <thioretic@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 125180 for review
Message-ID:  <200708151618.l7FGIoXS005507@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=125180

Change 125180 by thioretic@thioretic on 2007/08/15 16:17:50

	Some more io stuff.

Affected files ...

.. //depot/projects/soc2007/thioretic_gidl2/kern/subr_busio.c#4 edit
.. //depot/projects/soc2007/thioretic_gidl2/sys/bus.h#4 edit

Differences ...

==== //depot/projects/soc2007/thioretic_gidl2/kern/subr_busio.c#4 (text+ko) ====

@@ -7,6 +7,9 @@
 #include <sys/lock.h>
 #include <sys/mutex.h>
 #include <sys/uio.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/bus.h>
 
 static MALLOC_DEFINE(M_BUS_IO, "bus_io", "Bus io subsystem data structures");
 
@@ -23,6 +26,8 @@
 
 static struct mtx work_kthreads_list_mtx;
 
+int work_kthreads_to_wait_on;
+
 struct ior {
 #define OPEN	1
 #define FDOPEN	2
@@ -39,17 +44,21 @@
 #define SPARE2	13
 	u_int32_t type;
 	void* data;
-#define IORS_DONE	1<<0
-#define IORS_INVALIDATE	1<<1
-#define IORS_RETRY	1<<2
+#define IORS_NONE	0
+#define IORS_ENQUEUED	1<<0
+#define IORS_OWNED	1<<1
 	u_int32_t state;
+#define IORF_DONE	1<<0
+#define IORF_INVALIDATE	1<<1
+#define IORF_RETRY	1<<2
 	u_int32_t flags;
 	ior_link_list_t parents;
-	ior_link_list_t children;
+	/*ior_link_list_t*/ int children;
 	device_t origin;
 	devicelink_list_t path;
+	int queue_id;
 	
-	struct mtx guard_mtx;
+	struct mtx guard_spin_mtx;
 
 	TAILQ_ENTRY (ior) link;
 };
@@ -63,7 +72,16 @@
 
 typedef TAILQ_HEAD(ior_link_list, ior_link) ior_link_list_t;
 typedef TAILQ_HEAD(ior_list, ior) ior_list_t;
-static ior_list_t iors = TAILQ_HEAD_INITIALIZER(iors);
+
+struct ior_queue {
+	ior_list_t iors;
+	ior_t todo;
+	int flags;
+
+	struct mtx guard_spin_mtx;
+};
+
+static ior_queue ior_queues[IOR_QUEUES_NUM];
 
 static struct mtx iors_list_mtx;
 
@@ -86,6 +104,7 @@
 work_kthread_proc (void *arg){
 	static work_kthread_t my_pwk = ((work_kthread_t)arg);
 	struct thread *tp = FIRST_THREAD_IN_PROC(my_pwk->kthread);
+	int towait;
 
 	mtx_lock_spin (&sched_lock);
 	sched_prio (tp, );		/*TODO*/
@@ -100,7 +119,9 @@
 			kthread_exit (0);
 			return ();
 		}
-		bus_io_process_next_irp (my_pwk);
+		if (towait = bus_io_process_next_ior (my_pwk))
+			tsleep (&work_kthreads_to_wait_on,
+				, "no ior", 0);	/*TODO*/
 	}
 }
 
@@ -167,19 +188,60 @@
 
 void
 bus_io_init (void){
+	int i = 0;
+
 	mtx_init (&iors_list_mtx, 
 			"bus_io_iors_list_mtx",
 			NULL, MTX_DEF);
+
+	for (i = 0; i < IOR_QUEUES_NUM; i++){
+		ior_queues[i]->iors = TAILQ_HEAD_INITIALIZER(ior_queues[i]->iors);
+		mtx_init (&ior_queues[i]->guard_spin_mtx,
+			"ior_queue_mtx",
+			NULL, MTX_SPIN);
+	}
+
 	reset_work_kthreads();
 }
 
-static void 
+static int
 bus_io_process_next_ior (work_kthread_t wkt){
+	int qid = 0;
+	ior_queue q;
+	ior_t r;
+
+retry:
+	for (qid; qid < IOR_QUEUES_NUM; qid++){
+		q = ior_queues[qid];
+		if (r = q.todo)
+			break;
+	}
+	if (qid = IOR_QUEUES_NUM)
+		return (1);
+	
+	ior_lock (r);
+	mtx_lock_spin(&q.guard_spin_mtx);
+
+	if (r->state != IORS_ENQUEUED){
+		mtx_unlock_spin (&q.guard_spin_mtx);
+		ior_unlock (r);
+		goto retry;
+	}
+
+	q.todo = TAILQ_NEXT(r, link);
+	mtx_unlock_spin (&q.guard_spin_mtx);
+
+	r->state = IORS_OWNED;
+	ior_unlock (r);
+
+	//deliver ior to first in path driver
+
+	return (0);
 }
 
 ior_t
 create_ior (device_t origin, int type, void* data, 
-			ior_t* parents, int pcount, char* path){
+			ior_t* parents, int pcount, char* path, int enqueue){
 	ior_t new_ior;
 	ior_link_t il, il2, cil, *ils;
 	int i = 0, error = 0, path_len;
@@ -190,23 +252,21 @@
 	if (!new_ior)
 		return (NULL);
 
-	ils = malloc (sizeof(struct ior_link) * pcount * 2, M_BUS_IO,
+	ils = malloc (sizeof(struct ior_link) * pcount /* * 2*/, M_BUS_IO,	//REMOVE COMMENTS on type(ior->children) == ior_link_list_t
 		M_NOWAIT|M_ZERO);
 	if (!ils){
 		free (new_ior);
 		return (NULL);
 	}
 
-	mtx_init (&new_ior->guard_mtx,
-		"ior_mtx", NULL, MTX_DEF);
+	mtx_init (&new_ior->guard_spin_mtx,
+		"ior_mtx", NULL, MTX_SPIN);
 
 	if (error = ior_set_path (new_ior, origin, path)){
 		free (new_ior);	free (ils);
 		return (NULL);
 	}
 
-//	mtx_lock (&new_ior->guard_mtx);
-
 	new_ior->type = type;
 	new_ior->data = data;
 	for (i = 0; i < pcount; i++){
@@ -214,13 +274,17 @@
 		il->iorp = parents[i];
 		TAILQ_INSERT_TAIL (&new_ior->parents, il, link);
 		
-		il = ils++;
+		parents[i]->children++;
+/*		il = ils++;
 		il->iorp = new_ior;
 		TAILQ_INSERT_TAIL (&(parents[i])->children, il, link);
+*/	//REMOVE COMMENTS on type(ior->children) == ior_link_list_t
 	}
 	new_ior->origin = origin;
 
-//	mtx_unlock (&new_ior->guard_mtx);
+	if (enqueue){
+		ior_enqueue (new_ior);
+	}
 
 	return (new_ior);
 
@@ -237,7 +301,7 @@
 }
 
 void
-ior_get_flags (ior_t r, u_int32_t val){
+ior_set_flags (ior_t r, u_int32_t val){
 	r->flags = val;
 }
 
@@ -263,7 +327,7 @@
 		return (ENOMEM);
 	}
 
-	mtx_lock (&r->guard_mtx);
+	mtx_lock_spin (&r->guard_spin_mtx);
 
 	for (i = 0; i < path_len; i++){
 		dl->device_ptr = dev_path[i];
@@ -271,7 +335,7 @@
 		dl++;
 	}
 
-	mtx_unlock (&r->guard_mtx);
+	mtx_unlock_spin (&r->guard_spin_mtx);
 
 	free (dev_path);
 	return (0);
@@ -303,4 +367,78 @@
 	mtx_unlock (&r->path);
 
 	return (0);
-}+}
+
+static void	//static for now
+ior_enqueue_adv (ior_t r, int queue_id){
+	ior_queue q = ior_queues[queue_id];
+
+	ior_lock (r);
+	
+	if (r->state >= IORS_ENQUEUED){
+		ior_unlock (r);
+		return ();
+	}
+
+	mtx_lock_spin (&q.guard_spin_mtx);
+
+	TAILQ_INSERT_TAIL (&q.iors, r, link);
+	if (q.todo == NULL) 
+		q.todo = r;
+	
+	mtx_unlock_spin (&q.guard_spin_mtx);
+
+	r->queue_id = queue_id;
+	r->state = IORS_ENQUEUED;
+
+	ior_unlock (r);
+
+	wakeup_one (&work_kthreads_to_wait_on);
+}
+
+void
+ior_enqueue (ior_t r) {
+	return (ior_enqueue_adv (r, IOR_QUEUE_DEF));
+}
+
+static int
+ior_dequeue_adv (ior_t r, int queue_id){
+	int error = 0;
+	ior_queue q = ior_queues[queue_id];
+
+	ior_lock (r);
+	
+	if (r->state == IORS_NONE || r->children){
+			ior_unlock (r);
+			return (1);
+	}
+	
+	mtx_lock_spin (&q.guard_spin_mtx);
+	
+	if (q.todo == r)
+		q.todo = TAILQ_NEXT (r, link);
+	TAILQ_REMOVE (&q.iors, r, link);
+
+	mtx_unlock_spin (&q.quard_spin_mtx);
+
+	r->state = IORS_NONE;
+
+	ior_unlock (r);
+
+	return (error);
+}
+
+int
+ior_dequeue (ior_t r) {
+	return (ior_dequeue_adv (r, r->queue_id));
+}
+
+void
+ior_lock (ior_t r){
+	mtx_lock_spin (&r->guard_spin_mtx);
+}
+
+void
+ior_unlock (ior_t r){
+	mtx_unlock_spin (&r->guard_spin_mtx);
+}

==== //depot/projects/soc2007/thioretic_gidl2/sys/bus.h#4 (text+ko) ====

@@ -706,14 +706,22 @@
 #define bus_write_region_stream_8(r, o, d, c) \
 	bus_space_write_region_stream_8(rman_get_bustag(r), rman_get_bushandle(r), (o), (d), (c))
 
+#define IOR_QUEUES_NUM	1
+#define IOR_QUEUE_DEF	0
+
 int resolve_path (device_t origin, char* path, device_t **dev_path, int *path_len);
-ior_t create_ior (device_t origin, int type, void* data, ior_t* parents, int pcount, char* path)
-void ior_set_state (ior_t r, u_int32_t val);
-u_int32_t ior_get_state (ior_t r);
-void ior_get_flags (ior_t r, u_int32_t val);
-u_int32_t ior_get_flags (ior_t r);
+ior_t	create_ior (device_t origin, int type, void* data, ior_t* parents, int pcount, char* path)
+void	ior_set_state (ior_t r, u_int32_t val);
+u_int32_t   ior_get_state (ior_t r);
+void	ior_set_flags (ior_t r, u_int32_t val);
+u_int32_t   ior_get_flags (ior_t r);
 int ior_set_path (ior_t r, device_t origin, char* path);
 int ior_get_path (ior_t r, device_t **dev_path, int *path_len);
+void	ior_enqueue (ior_t r);
+int ior_dequeue (ior_t r);
+void	ior_lock (ior_t r);
+void	ior_unlock (ior_t r);
+
 
 #endif /* _KERNEL */
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200708151618.l7FGIoXS005507>