taskq - Make consumer tasks MPALMOSTSAFE
authorAlex Hornung <ahornung@gmail.com>
Fri, 2 Oct 2009 17:49:50 +0000 (18:49 +0100)
committerAlex Hornung <ahornung@gmail.com>
Fri, 2 Oct 2009 18:22:59 +0000 (19:22 +0100)
* All consumers of taskqueue_thread[cpu] have to be at least
  MPALMOSTSAFE as they won't be called with the mplock held.

sys/bus/cam/cam_xpt.c
sys/bus/cam/scsi/scsi_cd.c
sys/bus/cam/scsi/scsi_da.c
sys/kern/kern_exit.c

index b0ad8e5..c63b608 100644 (file)
@@ -2932,6 +2932,7 @@ xpt_action_sasync_cb(void *context, int pending)
        struct xpt_task *task;
        uint32_t added;
 
+       get_mplock();
        task = (struct xpt_task *)context;
        cur_entry = (struct async_node *)task->data1;
        added = task->data2;
@@ -2951,6 +2952,7 @@ xpt_action_sasync_cb(void *context, int pending)
                xpt_for_all_busses(xptsetasyncbusfunc, cur_entry);
        }
 
+       rel_mplock();
        kfree(task, M_CAMXPT);
 }
 
@@ -7042,6 +7044,7 @@ xpt_finishconfig_task(void *context, int pending)
        struct  periph_driver **p_drv;
        int     i;
 
+       get_mplock();
        kprintf("CAM: finished configuring all busses (%d left)\n",
                busses_to_config);
 
@@ -7066,6 +7069,7 @@ xpt_finishconfig_task(void *context, int pending)
                xsoftc.xpt_config_hook = NULL;
        }
 
+       rel_mplock();
        kfree(context, M_CAMXPT);
 }
 
index a5e4577..bf68bb0 100644 (file)
@@ -586,9 +586,12 @@ cdsysctlinit(void *context, int pending)
        struct cd_softc *softc;
        char tmpstr[80], tmpstr2[80];
 
+       get_mplock();
        periph = (struct cam_periph *)context;
-       if (cam_periph_acquire(periph) != CAM_REQ_CMP)
+       if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
+               rel_mplock();
                return;
+       }
 
        softc = (struct cd_softc *)periph->softc;
        ksnprintf(tmpstr, sizeof(tmpstr), "CAM CD unit %d", periph->unit_number);
@@ -603,6 +606,7 @@ cdsysctlinit(void *context, int pending)
        if (softc->sysctl_tree == NULL) {
                kprintf("cdsysctlinit: unable to allocate sysctl tree\n");
                cam_periph_release(periph);
+               rel_mplock();
                return;
        }
 
@@ -616,6 +620,7 @@ cdsysctlinit(void *context, int pending)
                        "Minimum CDB size");
 
        cam_periph_release(periph);
+       rel_mplock();
 }
 
 /*
index a56aa17..ebac23d 100644 (file)
@@ -945,9 +945,12 @@ dasysctlinit(void *context, int pending)
        struct da_softc *softc;
        char tmpstr[80], tmpstr2[80];
 
+       get_mplock();
        periph = (struct cam_periph *)context;
-       if (cam_periph_acquire(periph) != CAM_REQ_CMP)
+       if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
+               rel_mplock();
                return;
+       }
 
        softc = (struct da_softc *)periph->softc;
        ksnprintf(tmpstr, sizeof(tmpstr), "CAM DA unit %d", periph->unit_number);
@@ -961,6 +964,7 @@ dasysctlinit(void *context, int pending)
        if (softc->sysctl_tree == NULL) {
                kprintf("dasysctlinit: unable to allocate sysctl tree\n");
                cam_periph_release(periph);
+               rel_mplock();
                return;
        }
 
@@ -974,6 +978,7 @@ dasysctlinit(void *context, int pending)
                "Minimum CDB size");
 
        cam_periph_release(periph);
+       rel_mplock();
 }
 
 static int
index 65a0981..f940f00 100644 (file)
@@ -944,10 +944,12 @@ reaplwps(void *context, int dummy)
        struct lwplist *lwplist = context;
        struct lwp *lp;
 
+       get_mplock();
        while ((lp = LIST_FIRST(lwplist))) {
                LIST_REMOVE(lp, u.lwp_reap_entry);
                reaplwp(lp);
        }
+       rel_mplock();
 }
 
 static void