FreeBSD/sys/geom/eli/g_eli.c
/*
 * This is the main function for kernel worker thread when we don't have
 * hardware acceleration and we have to do cryptography in software.
 * Dedicated thread is needed, so we don't slow down g_up/g_down GEOM
 * threads with crypto work.
 */
This is the main function for kernel worker thread when we don't have
hardware acceleration and we have to do cryptography in software.
Dedicated thread is needed, so we don't slow down g_up/g_down GEOM
threads with crypto work.
This is the main function for kernel worker thread when we don ' t have hardware acceleration and we have to do cryptography in software . Dedicated thread is needed so we don ' t slow down g_up / g_down GEOM threads with crypto work .
static void
g_eli_worker(void *arg)
{
	struct g_eli_softc *sc;
	struct g_eli_worker *wr;
	struct bio *bp;
	int error;
	wr = arg;
	sc = wr->w_softc;
#ifdef EARLY_AP_STARTUP
	MPASS(!sc->sc_cpubind || smp_started);
#elif defined(SMP)
	if (sc->sc_cpubind) {
		while (!smp_started)
			tsleep(wr, 0, "geli:smp", hz / 4);
	}
#endif
	thread_lock(curthread);
	sched_prio(curthread, PUSER);
	if (sc->sc_cpubind)
		sched_bind(curthread, wr->w_number % mp_ncpus);
	thread_unlock(curthread);
	G_ELI_DEBUG(1, "Thread %s started.", curthread->td_proc->p_comm);
	for (;;) {
		mtx_lock(&sc->sc_queue_mtx);
again:
		bp = g_eli_takefirst(sc);
		if (bp == NULL) {
			if (sc->sc_flags & G_ELI_FLAG_DESTROY) {
				g_eli_cancel(sc);
				LIST_REMOVE(wr, w_next);
				g_eli_freesession(wr);
				free(wr, M_ELI);
				G_ELI_DEBUG(1, "Thread %s exiting.",
				    curthread->td_proc->p_comm);
				wakeup(&sc->sc_workers);
				mtx_unlock(&sc->sc_queue_mtx);
				kproc_exit(0);
			}
			while (sc->sc_flags & G_ELI_FLAG_SUSPEND) {
				if (sc->sc_inflight > 0) {
					G_ELI_DEBUG(0, "inflight=%d",
					    sc->sc_inflight);
					msleep(sc, &sc->sc_queue_mtx, PRIBIO,
					    "geli:inf", hz / 5);
					goto again;
				}
				if (wr->w_active) {
					g_eli_freesession(wr);
					wr->w_active = FALSE;
				}
				wakeup(&sc->sc_workers);
				msleep(sc, &sc->sc_queue_mtx, PRIBIO,
				    "geli:suspend", 0);
				if (!wr->w_active &&
				    !(sc->sc_flags & G_ELI_FLAG_SUSPEND)) {
					error = g_eli_newsession(wr);
					KASSERT(error == 0,
					    ("g_eli_newsession() failed on resume (error=%d)",
					    error));
					wr->w_active = TRUE;
				}
				goto again;
			}
			msleep(sc, &sc->sc_queue_mtx, PDROP, "geli:w", 0);
			continue;
		}
		if (bp->bio_pflags == G_ELI_NEW_BIO)
			atomic_add_int(&sc->sc_inflight, 1);
		mtx_unlock(&sc->sc_queue_mtx);
		if (bp->bio_pflags == G_ELI_NEW_BIO) {
			bp->bio_pflags = 0;
			if (sc->sc_flags & G_ELI_FLAG_AUTH) {
				if (bp->bio_cmd == BIO_READ)
					g_eli_auth_read(sc, bp);
				else
					g_eli_auth_run(wr, bp);
			} else {
				if (bp->bio_cmd == BIO_READ)
					g_eli_crypto_read(sc, bp, 1);
				else
					g_eli_crypto_run(wr, bp);
			}
		} else {
			if (sc->sc_flags & G_ELI_FLAG_AUTH)
				g_eli_auth_run(wr, bp);
			else
				g_eli_crypto_run(wr, bp);
		}
	}
}
static void g_eli_worker ( void * arg ) { struct g_eli_softc * sc ; struct g_eli_worker * wr ; struct bio * bp ; int error ; wr = arg ; sc = wr -> w_softc ; #ifdef EARLY_AP_STARTUP MPASS ( ! sc -> sc_cpubind || smp_started ) ; #elif defined ( SMP ) if ( sc -> sc_cpubind ) { while ( ! smp_started ) tsleep ( wr , 0 , " " , hz / 4 ) ; } #endif thread_lock ( curthread ) ; sched_prio ( curthread , PUSER ) ; if ( sc -> sc_cpubind ) sched_bind ( curthread , wr -> w_number % mp_ncpus ) ; thread_unlock ( curthread ) ; G_ELI_DEBUG ( 1 , " " , curthread -> td_proc -> p_comm ) ; for ( ; ; ) { mtx_lock ( & sc -> sc_queue_mtx ) ; again : bp = g_eli_takefirst ( sc ) ; if ( bp == NULL ) { if ( sc -> sc_flags & G_ELI_FLAG_DESTROY ) { g_eli_cancel ( sc ) ; LIST_REMOVE ( wr , w_next ) ; g_eli_freesession ( wr ) ; free ( wr , M_ELI ) ; G_ELI_DEBUG ( 1 , " " , curthread -> td_proc -> p_comm ) ; wakeup ( & sc -> sc_workers ) ; mtx_unlock ( & sc -> sc_queue_mtx ) ; kproc_exit ( 0 ) ; } while ( sc -> sc_flags & G_ELI_FLAG_SUSPEND ) { if ( sc -> sc_inflight > 0 ) { G_ELI_DEBUG ( 0 , " " , sc -> sc_inflight ) ; msleep ( sc , & sc -> sc_queue_mtx , PRIBIO , " " , hz / 5 ) ; goto again ; } if ( wr -> w_active ) { g_eli_freesession ( wr ) ; wr -> w_active = FALSE ; } wakeup ( & sc -> sc_workers ) ; msleep ( sc , & sc -> sc_queue_mtx , PRIBIO , " " , 0 ) ; if ( ! wr -> w_active && ! ( sc -> sc_flags & G_ELI_FLAG_SUSPEND ) ) { error = g_eli_newsession ( wr ) ; KASSERT ( error == 0 , ( " " , error ) ) ; wr -> w_active = TRUE ; } goto again ; } msleep ( sc , & sc -> sc_queue_mtx , PDROP , " " , 0 ) ; continue ; } if ( bp -> bio_pflags == G_ELI_NEW_BIO ) atomic_add_int ( & sc -> sc_inflight , 1 ) ; mtx_unlock ( & sc -> sc_queue_mtx ) ; if ( bp -> bio_pflags == G_ELI_NEW_BIO ) { bp -> bio_pflags = 0 ; if ( sc -> sc_flags & G_ELI_FLAG_AUTH ) { if ( bp -> bio_cmd == BIO_READ ) g_eli_auth_read ( sc , bp ) ; else g_eli_auth_run ( wr , bp ) ; } else { if ( bp -> bio_cmd == BIO_READ ) g_eli_crypto_read ( sc , bp , 1 ) ; else g_eli_crypto_run ( wr , bp ) ; } } else { if ( sc -> sc_flags & G_ELI_FLAG_AUTH ) g_eli_auth_run ( wr , bp ) ; else g_eli_crypto_run ( wr , bp ) ; } } }
This is the main function for kernel worker thread when we don't have
 hardware acceleration and we have to do cryptography in software.
This is the main function for kernel worker thread when we don ' t have hardware acceleration and we have to do cryptography in software .
/* Before sched_bind() to a CPU, wait for all CPUs to go on-line. */ /*
					 * We still have inflight BIOs, so
					 * sleep and retry.
					 */ /*
				 * Suspend requested, mark the worker as
				 * suspended and go to sleep.
				 */