On Tue, Jul 07, 2009 at 10:47:51PM +0200, Joerg Sonnenberger wrote: > On Tue, Jul 07, 2009 at 01:26:13PM -0500, David Young wrote: > > How is this for a fix? I haven't run-tested this, yet. > > Wouldn't a pool serve the same purpose with less code?
I don't see why not. See attachment. Dave -- David Young OJC Technologies dyo...@ojctech.com Urbana, IL * (217) 278-3933
Index: sys/kern/kern_pmf.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_pmf.c,v retrieving revision 1.27 diff -p -u -u -p -r1.27 kern_pmf.c --- sys/kern/kern_pmf.c 26 Jun 2009 19:30:45 -0000 1.27 +++ sys/kern/kern_pmf.c 7 Jul 2009 23:27:10 -0000 @@ -89,15 +100,20 @@ static TAILQ_HEAD(, pmf_event_handler) p TAILQ_HEAD_INITIALIZER(pmf_all_events); typedef struct pmf_event_workitem { struct work pew_work; pmf_generic_event_t pew_event; device_t pew_device; } pmf_event_workitem_t; +static struct pool_cache pew_pc; + +static pmf_event_workitem_t *pmf_event_workitem_get(void); +static void pmf_event_workitem_put(pmf_event_workitem_t *); + static bool pmf_device_resume_locked(device_t PMF_FN_PROTO); static bool pmf_device_suspend_locked(device_t PMF_FN_PROTO); static void pmf_event_worker(struct work *wk, void *dummy) @@ -116,7 +200,7 @@ pmf_event_worker(struct work *wk, void * (*event->pmf_handler)(event->pmf_device); } - kmem_free(pew, sizeof(*pew)); + pmf_event_workitem_put(pew); } static bool @@ -555,7 +925,7 @@ pmf_event_inject(device_t dv, pmf_generi { pmf_event_workitem_t *pew; - pew = kmem_alloc(sizeof(pmf_event_workitem_t), KM_NOSLEEP); + pew = pmf_event_workitem_get(); if (pew == NULL) { PMF_EVENT_PRINTF(("%s: PMF event %d dropped (no memory)\n", dv ? device_xname(dv) : "<anonymous>", ev)); @@ -686,17 +1056,42 @@ pmf_class_display_register(device_t dv) return true; } +static void +pmf_event_workitem_put(pmf_event_workitem_t *pew) +{ + KASSERT(pew != NULL); + pool_cache_put(&pew_pc, pew); +} + +static pmf_event_workitem_t * +pmf_event_workitem_get(void) +{ + return pool_cache_get(&pew_pc, PR_NOWAIT); +} + +static int +pew_constructor(void *arg, void *obj, int flags) +{ + memset(obj, 0, sizeof(pmf_event_workitem_t)); + return 0; +} + void pmf_init(void) { int err; + pool_cache_init(sizeof(pmf_event_workitem_t), 0, 0, 0, "pew pool", + NULL, IPL_HIGH, pew_constructor, NULL, NULL); + pool_cache_setlowat(&pew_pc, 16); + pool_cache_sethiwat(&pew_pc, 256); + KASSERT(pmf_event_workqueue == NULL); err = workqueue_create(&pmf_event_workqueue, "pmfevent", pmf_event_worker, NULL, PRI_NONE, IPL_VM, 0); if (err) panic("couldn't create pmfevent workqueue"); callout_init(&global_idle_counter, 0); callout_setfunc(&global_idle_counter, input_idle, NULL); }