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>