mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-16 10:20:30 +00:00
Add a new per-thread private flag: TDP_GEOM.
This flag gets set whenever the thread posts an event on the GEOM event queue, and if the flag is set when the thread is prepared to return to userland from the kernel, g_waitidle() will be called to make sure that the posted events have completed. This can replace an insufficient number of g_waitidle() calls in various other places, and has the advantage of being failsafe: Any system call which does a VOP_OPEN()/VOP_CLOSE will now correctly wait for any geom events it posted as part of spoils or tastes. Assert that topology and Giant is not held in g_waitidle().
This commit is contained in:
parent
a11021f362
commit
9197ce2ee5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=136837
@ -47,12 +47,14 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <machine/stdarg.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <geom/geom.h>
|
||||
#include <geom/geom_int.h>
|
||||
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
TAILQ_HEAD(event_tailq_head, g_event);
|
||||
|
||||
static struct event_tailq_head g_events = TAILQ_HEAD_INITIALIZER(g_events);
|
||||
@ -79,8 +81,12 @@ void
|
||||
g_waitidle(void)
|
||||
{
|
||||
|
||||
g_topology_assert_not();
|
||||
mtx_assert(&Giant, MA_NOTOWNED);
|
||||
|
||||
while (g_pending_events)
|
||||
tsleep(&g_pending_events, PPAUSE, "g_waitidle", hz/5);
|
||||
curthread->td_pflags &= ~TDP_GEOM;
|
||||
}
|
||||
|
||||
void
|
||||
@ -279,6 +285,7 @@ g_post_event_x(g_event_t *func, void *arg, int flag, int wuflag, struct g_event
|
||||
wakeup(&g_wait_event);
|
||||
if (epp != NULL)
|
||||
*epp = ep;
|
||||
curthread->td_pflags |= TDP_GEOM;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -94,6 +94,13 @@ userret(td, frame, oticks)
|
||||
PROC_UNLOCK(p);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If this thread tickled GEOM, we need to wait for the giggling to
|
||||
* stop before we return to userland
|
||||
*/
|
||||
if (td->td_pflags & TDP_GEOM)
|
||||
g_waitidle();
|
||||
|
||||
/*
|
||||
* Let the scheduler adjust our priority etc.
|
||||
*/
|
||||
|
@ -375,6 +375,7 @@ struct thread {
|
||||
#define TDP_SCHED2 0x00002000 /* Reserved for scheduler private use */
|
||||
#define TDP_SCHED3 0x00004000 /* Reserved for scheduler private use */
|
||||
#define TDP_SCHED4 0x00008000 /* Reserved for scheduler private use */
|
||||
#define TDP_GEOM 0x00010000 /* Settle GEOM before finishing syscall */
|
||||
|
||||
/*
|
||||
* Reasons that the current thread can not be run yet.
|
||||
|
Loading…
Reference in New Issue
Block a user