Source-Changes-D archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: CVS commit: src/sys
On Tue, Jul 07, 2009 at 07:10:15PM +0100, Mindaugas Rasiukevicius wrote:
> > > Module Name: src
> > > Committed By: dyoung
> > > Date: Fri Jun 26 19:30:46 UTC 2009
> > >
> > > Modified Files:
> > > src/sys/kern: kern_pmf.c subr_autoconf.c
> > > src/sys/sys: device.h
> > >
> > > Log Message:
> > > Switch to kmem(9).
> > >
> > > (void *)pew is one way to get a struct work *, but let's
> > > write&pew->pew_work, instead. It is more defensive and persuasive.
> > >
> >
> > It seems that pmf_event_inject() is called from interrupt context, from
> > which kmem(9) cannot be used. You probably want to use pool_cache(9), or
> > perhaps avoid allocations at all (since they are not intensive).
> >
>
> Are you planning to fix it? It should probably be reverted, if takes a while.
How is this for a fix? I haven't run-tested this, yet.
Dave
--
David Young OJC Technologies
dyoung%ojctech.com@localhost 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 18:18:23 -0000
@@ -89,11 +100,19 @@ 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;
+ struct work pew_work;
+ pmf_generic_event_t pew_event;
+ device_t pew_device;
+ SIMPLEQ_ENTRY(pmf_event_workitem) pew_next_free;
} pmf_event_workitem_t;
+static kmutex_t pew_mtx;
+static pmf_event_workitem_t pew_array[16];
+static SIMPLEQ_HEAD(, pmf_event_workitem) pew_list =
+ SIMPLEQ_HEAD_INITIALIZER(pew_list);
+
+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);
@@ -116,7 +203,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 +928,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,10 +1059,41 @@ pmf_class_display_register(device_t dv)
return true;
}
+static void
+pmf_event_workitem_put(pmf_event_workitem_t *pew)
+{
+ KASSERT(pew != NULL);
+ mutex_enter(&pew_mtx);
+ SIMPLEQ_INSERT_HEAD(&pew_list, pew, pew_next_free);
+ mutex_exit(&pew_mtx);
+}
+
+static pmf_event_workitem_t *
+pmf_event_workitem_get(void)
+{
+ pmf_event_workitem_t *pew;
+
+ mutex_enter(&pew_mtx);
+ if ((pew = SIMPLEQ_FIRST(&pew_list)) != NULL) {
+ SIMPLEQ_REMOVE_HEAD(&pew_list, pew_next_free);
+ memset(pew, 0, sizeof(*pew));
+ }
+ mutex_exit(&pew_mtx);
+
+ return pew;
+}
+
void
pmf_init(void)
{
- int err;
+ int err, i;
+
+ mutex_init(&pew_mtx, MUTEX_DEFAULT, IPL_HIGH);
+
+ SIMPLEQ_INIT(&pew_list);
+
+ for (i = __arraycount(pew_array); --i >= 0; )
+ SIMPLEQ_INSERT_HEAD(&pew_list, &pew_array[i], pew_next_free);
KASSERT(pmf_event_workqueue == NULL);
err = workqueue_create(&pmf_event_workqueue, "pmfevent",
Home |
Main Index |
Thread Index |
Old Index