PERFORCE change 96929 for review
John Birrell
jb at FreeBSD.org
Wed May 10 22:05:09 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=96929
Change 96929 by jb at jb_freebsd2 on 2006/05/10 22:04:53
Implement the software interrupts CY_LOW_LEVEL and CY_LOCK_LEVEL.
Map them to SWI_TQ and SWI_TQ_FAST.
Enable the semaphores.
This brings us to another milestone... the 'profile' provider works
now. Only on a single CPU machine though. We still need a way to
execute a task on another CPU.
Affected files ...
.. //depot/projects/dtrace/src/sys/cddl/i386/cyclic_machdep.c#2 edit
.. //depot/projects/dtrace/src/sys/cddl/kern/cyclic.c#2 edit
.. //depot/projects/dtrace/src/sys/cddl/kern/kern_cyclic.c#2 edit
Differences ...
==== //depot/projects/dtrace/src/sys/cddl/i386/cyclic_machdep.c#2 (text+ko) ====
@@ -29,8 +29,10 @@
#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/interrupt.h>
+#include <sys/kernel.h>
#include <sys/pcpu.h>
-#include <sys/kernel.h>
#include <sys/cyclic_impl.h>
extern cyclic_clock_func_t lapic_cyclic_clock_func;
@@ -62,8 +64,29 @@
NULL /* cyb_arg_t cyb_arg */
};
+static hrtime_t resolution;
static int hpet_present = 0;
-static hrtime_t resolution;
+static void *cyclic_lock_ih;
+static void *cyclic_low_ih;
+
+/*
+ * Software interrupt callbacks.
+ */
+static void
+cyclic_swi_low(void *dummy)
+{
+ cpu_t *c = pcpu_find(curcpu);
+
+ cyclic_softint(c, CY_LOW_LEVEL);
+}
+
+static void
+cyclic_swi_lock(void *dummy)
+{
+ cpu_t *c = pcpu_find(curcpu);
+
+ cyclic_softint(c, CY_LOCK_LEVEL);
+}
/*
* Machine dependent cyclic subsystem initialisation.
@@ -76,6 +99,15 @@
/* XXX Need to check here if the HPET is available. */
+ /*
+ * Add a software interrupt handlers for low priority cyclic
+ * events.
+ */
+ swi_add(&clk_intr_event, "low cyclic", cyclic_swi_low, NULL,
+ SWI_TQ, 0, &cyclic_low_ih);
+ swi_add(&clk_intr_event, "lock cyclic", cyclic_swi_lock, NULL,
+ SWI_TQ_FAST, 0, &cyclic_lock_ih);
+
/* Register the cyclic backend. */
cyclic_init(&be, resolution);
@@ -93,6 +125,10 @@
/* De-register the cyclic backend. */
cyclic_uninit();
+
+ /* Remove the software interrupt handlers. */
+ swi_remove(cyclic_low_ih);
+ swi_remove(cyclic_lock_ih);
}
static cyb_arg_t configure(cpu_t *c)
@@ -125,7 +161,21 @@
static void softint(cyb_arg_t arg, cyc_level_t level)
{
- printf("%s:%s(%d): Huh?\n",__FUNCTION__,__FILE__,__LINE__);
+ /*
+ * Schedule the software interrupt processing at the
+ * requested level.
+ */
+ switch (level) {
+ case CY_LOW_LEVEL:
+ swi_sched(cyclic_low_ih, 0);
+ break;
+ case CY_LOCK_LEVEL:
+ swi_sched(cyclic_lock_ih, 0);
+ break;
+ default:
+ printf("%s:%s(%d): unexpected soft level %d\n",__FUNCTION__,__FILE__,__LINE__,level);
+ break;
+ }
}
static cyc_cookie_t set_level(cyb_arg_t arg, cyc_level_t level)
==== //depot/projects/dtrace/src/sys/cddl/kern/cyclic.c#2 (text+ko) ====
@@ -484,7 +484,7 @@
*
* cyclic_expand() blocks on the cyp_modify_wait semaphore (a semaphore is
* used instead of a condition variable because of the race between the
- * sema_p() in cyclic_expand() and the sema_v() in cyclic_softint()). This
+ * sema_wait() in cyclic_expand() and the sema_post() in cyclic_softint()). This
* allows cyclic_expand() to know when the resize operation is complete;
* all of the old buffers (the heap, the cyclics array and the producer/
* consumer buffers) can be freed.
@@ -560,12 +560,14 @@
#include <sys/types.h>
#include <sys/kernel.h>
#include <sys/kmem.h>
+#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/pcpu.h>
#include <sys/smp.h>
#include <sys/stdint.h>
#include <sys/time.h>
#include <sys/cyclic_impl.h>
+#include <machine/atomic.h>
MALLOC_DECLARE(M_CYCLIC);
MALLOC_DEFINE(M_CYCLIC, "cyclic", "Cyclic Subsystem");
@@ -811,8 +813,6 @@
cyc_backend_t *be = cpu->cyp_backend;
cyc_level_t level = cyclic->cy_level;
-/* XXX Force everything via the CY_HIGH_LEVEL */
-level = CY_HIGH_LEVEL;
/*
* If this is a CY_HIGH_LEVEL cyclic, just call the handler; we don't
* need to worry about the pend count for CY_HIGH_LEVEL cyclics.
@@ -979,7 +979,6 @@
c->pc_ncyclic = cpu->cyp_nelems;
}
-#ifdef DOODAD
static void
cyclic_remove_pend(cyc_cpu_t *cpu, cyc_level_t level, cyclic_t *cyclic)
{
@@ -1007,7 +1006,7 @@
/*
* We can now let the remove operation complete.
*/
- sema_v(&cpu->cyp_modify_wait);
+ sema_post(&cpu->cyp_modify_wait);
}
/*
@@ -1061,7 +1060,7 @@
void
cyclic_softint(cpu_t *c, cyc_level_t level)
{
- cyc_cpu_t *cpu = c->cpu_cyclic;
+ cyc_cpu_t *cpu = c->pc_cyclic;
cyc_softbuf_t *softbuf;
int soft, *buf, consndx, resized = 0, intr_resized = 0;
cyc_pcbuffer_t *pc;
@@ -1157,7 +1156,7 @@
}
if ((opend =
- cas32(&cyclic->cy_pend, pend, npend)) != pend) {
+ atomic_cmpset_int(&cyclic->cy_pend, pend, npend)) != pend) {
/*
* Our cas32 can fail for one of several
* reasons:
@@ -1249,7 +1248,7 @@
do {
lev = cpu->cyp_modify_levels;
nlev = lev + 1;
- } while (cas32(&cpu->cyp_modify_levels, lev, nlev) != lev);
+ } while (atomic_cmpset_int(&cpu->cyp_modify_levels, lev, nlev) != lev);
/*
* If we are the last soft level to see the modification,
@@ -1258,7 +1257,7 @@
*/
if (nlev == CY_SOFT_LEVELS) {
CYC_TRACE0(cpu, level, "resize-kick");
- sema_v(&cpu->cyp_modify_wait);
+ sema_post(&cpu->cyp_modify_wait);
} else {
ASSERT(nlev < CY_SOFT_LEVELS);
if (level != CY_LOW_LEVEL) {
@@ -1270,7 +1269,6 @@
}
}
}
-#endif
static void
cyclic_expand_xcall(cyc_xcallarg_t *arg)
@@ -1436,9 +1434,7 @@
/*
* Now block, waiting for the resize operation to complete.
*/
-#ifdef DOODAD
- sema_p(&cpu->cyp_modify_wait);
-#endif
+ sema_wait(&cpu->cyp_modify_wait);
ASSERT(cpu->cyp_modify_levels == CY_SOFT_LEVELS);
/*
@@ -1879,10 +1875,8 @@
return (0);
}
-#ifdef DOODAD
if (cpu->cyp_rpend != 0)
- sema_p(&cpu->cyp_modify_wait);
-#endif
+ sema_wait(&cpu->cyp_modify_wait);
ASSERT(cpu->cyp_state == CYS_REMOVING);
@@ -1969,9 +1963,7 @@
if (delay > (cyclic->cy_interval >> 1))
delay = cyclic->cy_interval >> 1;
-#ifdef DOODAD
- drv_usecwait((clock_t)(delay / (NANOSEC / MICROSEC)));
-#endif
+ DELAY((int)(delay / (NANOSEC / MICROSEC)));
}
/*
@@ -2148,9 +2140,7 @@
cpu->cyp_cpu = c;
-#ifdef DOODAD
- sema_init(&cpu->cyp_modify_wait, 0, NULL, SEMA_DEFAULT, NULL);
-#endif
+ sema_init(&cpu->cyp_modify_wait, 0, "cyclic modify");
cpu->cyp_size = 1;
cpu->cyp_heap = kmem_zalloc(sizeof (cyc_index_t), KM_SLEEP);
@@ -2231,6 +2221,8 @@
pc->cypc_buf = NULL;
}
+ sema_destroy(&cpu->cyp_modify_wait);
+
/*
* Finally, clean up our remaining dynamic structures and NULL out
* the cpu_cyclic pointer.
@@ -2637,19 +2629,20 @@
cyclic_add_omni(cyc_omni_handler_t *omni)
{
cyc_id_t *idp = cyclic_new_id();
-printf("%s: DOODAD\n",__FUNCTION__);
-#ifdef DOODAD
cyc_cpu_t *cpu;
cpu_t *c;
+ int id;
ASSERT(MUTEX_HELD(&cpu_lock));
ASSERT(omni != NULL && omni->cyo_online != NULL);
idp->cyi_omni_hdlr = *omni;
- c = cpu_list;
- do {
- if ((cpu = c->cpu_cyclic) == NULL)
+ for (id = 0; id <= mp_maxid; id++) {
+ if ((c = pcpu_find(id)) == NULL)
+ continue;
+
+ if ((cpu = c->pc_cyclic) == NULL)
continue;
if (cpu->cyp_state != CYS_ONLINE) {
@@ -2658,7 +2651,7 @@
}
cyclic_omni_start(idp, cpu);
- } while ((c = c->cpu_next) != cpu_list);
+ }
/*
* We must have found at least one online CPU on which to run
@@ -2666,7 +2659,6 @@
*/
ASSERT(idp->cyi_omni_list != NULL);
ASSERT(idp->cyi_cpu == NULL);
-#endif
return ((uintptr_t)idp);
}
==== //depot/projects/dtrace/src/sys/cddl/kern/kern_cyclic.c#2 (text+ko) ====
@@ -30,9 +30,9 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
-#include <sys/pcpu.h>
#include <sys/kernel.h>
#include <sys/module.h>
+#include <sys/pcpu.h>
#include <sys/cyclic.h>
/*
@@ -41,6 +41,7 @@
static void
cyclic_load(void *dummy)
{
+ /* Initialise the machine-dependent backend. */
cyclic_machdep_init();
}
@@ -49,8 +50,10 @@
static void
cyclic_unload(void)
{
+ /* Uninitialise the machine-dependent backend. */
cyclic_machdep_uninit();
}
+
SYSUNINIT(ata_unregister, SI_SUB_CLOCKS, SI_ORDER_SECOND, cyclic_unload, NULL);
/*
More information about the p4-projects
mailing list