Calling KNOTE with locks held may result in recursion when it calls back

into targreadfilt().  Unlock around calls to notify_user().  If an application
is sending CCBs while the endpoint is shutting down, this may result in
incomplete disable.  A more complete solution will come with a "dying" flag.

Submitted by:	simokawa
This commit is contained in:
Nate Lawson 2003-09-04 16:30:03 +00:00
parent 5512662bdf
commit faf9513401

View File

@ -823,6 +823,7 @@ targdone(struct cam_periph *periph, union ccb *done_ccb)
case XPT_CONT_TARGET_IO:
TAILQ_INSERT_TAIL(&softc->user_ccb_queue, &done_ccb->ccb_h,
periph_links.tqe);
TARG_UNLOCK(softc);
notify_user(softc);
break;
default:
@ -830,7 +831,6 @@ targdone(struct cam_periph *periph, union ccb *done_ccb)
done_ccb->ccb_h.func_code);
/* NOTREACHED */
}
TARG_UNLOCK(softc);
}
/* Return CCBs to the user from the user queue and abort queue */
@ -1096,8 +1096,19 @@ abort_all_pending(struct targ_softc *softc)
/* If we aborted anything from the work queue, wakeup user. */
if (!TAILQ_EMPTY(&softc->user_ccb_queue)
|| !TAILQ_EMPTY(&softc->abort_queue))
|| !TAILQ_EMPTY(&softc->abort_queue)) {
/*
* XXX KNOTE calls back into targreadfilt, causing a
* lock recursion. So unlock around calls to it although
* this may open up a race allowing a user to submit
* another CCB after we have aborted all pending ones
* A better approach is to mark the softc as dying
* under lock and check for this in targstart().
*/
TARG_UNLOCK(softc);
notify_user(softc);
TARG_LOCK(softc);
}
}
/* Notify the user that data is ready */