From owner-p4-projects@FreeBSD.ORG Tue Aug 26 13:48:20 2003 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 3711916A4C1; Tue, 26 Aug 2003 13:48:20 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D469216A4BF for ; Tue, 26 Aug 2003 13:48:19 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id ECEC443FCB for ; Tue, 26 Aug 2003 13:48:18 -0700 (PDT) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h7QKmI0U012814 for ; Tue, 26 Aug 2003 13:48:18 -0700 (PDT) (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h7QKmIox012811 for perforce@freebsd.org; Tue, 26 Aug 2003 13:48:18 -0700 (PDT) Date: Tue, 26 Aug 2003 13:48:18 -0700 (PDT) Message-Id: <200308262048.h7QKmIox012811@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Subject: PERFORCE change 36979 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 Aug 2003 20:48:20 -0000 http://perforce.freebsd.org/chv.cgi?CH=36979 Change 36979 by sam@sam_ebb on 2003/08/26 13:47:31 fast swi taskqueue support; for queueing swi's from a fast isr Affected files ... .. //depot/projects/netperf/sys/kern/subr_taskqueue.c#2 edit .. //depot/projects/netperf/sys/sys/interrupt.h#2 edit .. //depot/projects/netperf/sys/sys/taskqueue.h#2 edit Differences ... ==== //depot/projects/netperf/sys/kern/subr_taskqueue.c#2 (text+ko) ==== @@ -240,3 +240,121 @@ TASKQUEUE_DEFINE(swi_giant, taskqueue_swi_giant_enqueue, 0, swi_add(NULL, "Giant task queue", taskqueue_swi_giant_run, NULL, SWI_TQ_GIANT, 0, &taskqueue_giant_ih)); + +int +taskqueue_enqueue_fast(struct taskqueue *queue, struct task *task) +{ + struct task *ins; + struct task *prev; + + mtx_lock_spin(&queue->tq_mutex); + + /* + * Don't allow new tasks on a queue which is being freed. + */ + if (queue->tq_draining) { + mtx_unlock_spin(&queue->tq_mutex); + return EPIPE; + } + + /* + * Count multiple enqueues. + */ + if (task->ta_pending) { + task->ta_pending++; + mtx_unlock_spin(&queue->tq_mutex); + return 0; + } + + /* + * Optimise the case when all tasks have the same priority. + */ + prev = STAILQ_LAST(&queue->tq_queue, task, ta_link); + if (!prev || prev->ta_priority >= task->ta_priority) { + STAILQ_INSERT_TAIL(&queue->tq_queue, task, ta_link); + } else { + prev = 0; + for (ins = STAILQ_FIRST(&queue->tq_queue); ins; + prev = ins, ins = STAILQ_NEXT(ins, ta_link)) + if (ins->ta_priority < task->ta_priority) + break; + + if (prev) + STAILQ_INSERT_AFTER(&queue->tq_queue, prev, task, ta_link); + else + STAILQ_INSERT_HEAD(&queue->tq_queue, task, ta_link); + } + + task->ta_pending = 1; + if (queue->tq_enqueue) + queue->tq_enqueue(queue->tq_context); + + mtx_unlock_spin(&queue->tq_mutex); + + return 0; +} + +static void +taskqueue_run_fast(struct taskqueue *queue) +{ + struct task *task; + int pending; + + mtx_lock_spin(&queue->tq_mutex); + while (STAILQ_FIRST(&queue->tq_queue)) { + /* + * Carefully remove the first task from the queue and + * zero its pending count. + */ + task = STAILQ_FIRST(&queue->tq_queue); + STAILQ_REMOVE_HEAD(&queue->tq_queue, ta_link); + pending = task->ta_pending; + task->ta_pending = 0; + mtx_unlock_spin(&queue->tq_mutex); + + task->ta_func(task->ta_context, pending); + + mtx_lock_spin(&queue->tq_mutex); + } + mtx_unlock_spin(&queue->tq_mutex); +} + +struct taskqueue *taskqueue_fast; +static void *taskqueue_fast_ih; + +static void +taskqueue_fast_schedule(void *context) +{ + swi_sched(taskqueue_fast_ih, 0); +} + +static void +taskqueue_fast_run(void *dummy) +{ + taskqueue_run_fast(taskqueue_fast); +} + +static void +taskqueue_define_fast(void *arg) +{ + taskqueue_fast = malloc(sizeof(struct taskqueue), + M_TASKQUEUE, M_NOWAIT | M_ZERO); + if (!taskqueue_fast) { + printf("%s: Unable to allocate fast task queue!\n", __func__); + return; + } + + STAILQ_INIT(&taskqueue_fast->tq_queue); + taskqueue_fast->tq_name = "fast"; + taskqueue_fast->tq_enqueue = taskqueue_fast_schedule; + mtx_init(&taskqueue_fast->tq_mutex, "taskqueue", NULL, MTX_SPIN); + + mtx_lock(&taskqueue_queues_mutex); + STAILQ_INSERT_TAIL(&taskqueue_queues, taskqueue_fast, tq_link); + mtx_unlock(&taskqueue_queues_mutex); + + swi_add(NULL, "Fast task queue", taskqueue_fast_run, + NULL, SWI_TQ_FAST, 0, &taskqueue_fast_ih); +} +SYSINIT(taskqueue_fast, SI_SUB_CONFIGURE, SI_ORDER_SECOND, + taskqueue_define_fast, NULL); ==== //depot/projects/netperf/sys/sys/interrupt.h#2 (text+ko) ==== @@ -94,9 +94,10 @@ #define SWI_CAMNET 2 #define SWI_CAMBIO 3 #define SWI_VM 4 -#define SWI_TQ_GIANT 5 -#define SWI_TQ 6 -#define SWI_CLOCK 7 +#define SWI_TQ_FAST 5 +#define SWI_TQ_GIANT 6 +#define SWI_TQ 7 +#define SWI_CLOCK 8 extern struct ithd *tty_ithd; extern struct ithd *clk_ithd; ==== //depot/projects/netperf/sys/sys/taskqueue.h#2 (text+ko) ==== @@ -113,4 +113,13 @@ TASKQUEUE_DECLARE(swi_giant); TASKQUEUE_DECLARE(swi); +/* + * Queue for swi handlers dispatched from fast interrupt handlers. + * These are necessarily different from the above because the queue + * must be locked with spinlocks since sleep mutex's cannot be used + * from a fast interrupt handler context. + */ +TASKQUEUE_DECLARE(fast); +int taskqueue_enqueue_fast(struct taskqueue *queue, struct task *task); + #endif /* !_SYS_TASKQUEUE_H_ */