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