FreeBSD/sys/dev/ioat/ioat.c
/*
 * Reserves space in this IOAT descriptor ring by ensuring enough slots remain
 * for 'num_descs'.
 *
 * If mflags contains M_WAITOK, blocks until enough space is available.
 *
 * Returns zero on success, or an errno on error.  If num_descs is beyond the
 * maximum ring size, returns EINVAl; if allocation would block and mflags
 * contains M_NOWAIT, returns EAGAIN.
 *
 * Must be called with the submit_lock held; returns with the lock held.  The
 * lock may be dropped to allocate the ring.
 *
 * (The submit_lock is needed to add any entries to the ring, so callers are
 * assured enough room is available.)
 */
Reserves space in this IOAT descriptor ring by ensuring enough slots remain
for 'num_descs'.

If mflags contains M_WAITOK, blocks until enough space is available.

Returns zero on success, or an errno on error.  If num_descs is beyond the
maximum ring size, returns EINVAl; if allocation would block and mflags
contains M_NOWAIT, returns EAGAIN.

Must be called with the submit_lock held; returns with the lock held.  The
lock may be dropped to allocate the ring.

(The submit_lock is needed to add any entries to the ring, so callers are
assured enough room is available.)
Reserves space in this IOAT descriptor ring by ensuring enough slots remain for ' num_descs ' . If mflags contains M_WAITOK blocks until enough space is available . Returns zero on success or an errno on error . If num_descs is beyond the maximum ring size returns EINVAl ; if allocation would block and mflags contains M_NOWAIT returns EAGAIN . Must be called with the submit_lock held ; returns with the lock held . The lock may be dropped to allocate the ring . ( The submit_lock is needed to add any entries to the ring so callers are assured enough room is available . )
static int
ioat_reserve_space(struct ioat_softc *ioat, uint32_t num_descs, int mflags)
{
	struct ioat_descriptor **new_ring;
	uint32_t order;
	int error;
	mtx_assert(&ioat->submit_lock, MA_OWNED);
	error = 0;
	if (num_descs < 1 || num_descs > (1 << IOAT_MAX_ORDER)) {
		error = EINVAL;
		goto out;
	}
	if (ioat->quiescing) {
		error = ENXIO;
		goto out;
	}
	for (;;) {
		if (ioat_get_ring_space(ioat) >= num_descs)
			goto out;
		order = ioat->ring_size_order;
		if (ioat->is_resize_pending || order == IOAT_MAX_ORDER) {
			if ((mflags & M_WAITOK) != 0) {
				msleep(&ioat->tail, &ioat->submit_lock, 0,
				    "ioat_rsz", 0);
				continue;
			}
			error = EAGAIN;
			break;
		}
		ioat->is_resize_pending = TRUE;
		for (;;) {
			mtx_unlock(&ioat->submit_lock);
			new_ring = ioat_prealloc_ring(ioat, 1 << (order + 1),
			    TRUE, mflags);
			mtx_lock(&ioat->submit_lock);
			KASSERT(ioat->ring_size_order == order,
			    ("is_resize_pending should protect order"));
			if (new_ring == NULL) {
				KASSERT((mflags & M_WAITOK) == 0,
				    ("allocation failed"));
				error = EAGAIN;
				break;
			}
			error = ring_grow(ioat, order, new_ring);
			if (error == 0)
				break;
		}
		ioat->is_resize_pending = FALSE;
		wakeup(&ioat->tail);
		if (error)
			break;
	}
out:
	mtx_assert(&ioat->submit_lock, MA_OWNED);
	return (error);
}
static int ioat_reserve_space ( struct ioat_softc * ioat , uint32_t num_descs , int mflags ) { struct ioat_descriptor * * new_ring ; uint32_t order ; int error ; mtx_assert ( & ioat -> submit_lock , MA_OWNED ) ; error = 0 ; if ( num_descs < 1 || num_descs > ( 1 << IOAT_MAX_ORDER ) ) { error = EINVAL ; goto out ; } if ( ioat -> quiescing ) { error = ENXIO ; goto out ; } for ( ; ; ) { if ( ioat_get_ring_space ( ioat ) >= num_descs ) goto out ; order = ioat -> ring_size_order ; if ( ioat -> is_resize_pending || order == IOAT_MAX_ORDER ) { if ( ( mflags & M_WAITOK ) != 0 ) { msleep ( & ioat -> tail , & ioat -> submit_lock , 0 , " " , 0 ) ; continue ; } error = EAGAIN ; break ; } ioat -> is_resize_pending = TRUE ; for ( ; ; ) { mtx_unlock ( & ioat -> submit_lock ) ; new_ring = ioat_prealloc_ring ( ioat , 1 << ( order + 1 ) , TRUE , mflags ) ; mtx_lock ( & ioat -> submit_lock ) ; KASSERT ( ioat -> ring_size_order == order , ( " " ) ) ; if ( new_ring == NULL ) { KASSERT ( ( mflags & M_WAITOK ) == 0 , ( " " ) ) ; error = EAGAIN ; break ; } error = ring_grow ( ioat , order , new_ring ) ; if ( error == 0 ) break ; } ioat -> is_resize_pending = FALSE ; wakeup ( & ioat -> tail ) ; if ( error ) break ; } out : mtx_assert ( & ioat -> submit_lock , MA_OWNED ) ; return ( error ) ; }
Reserves space in this IOAT descriptor ring by ensuring enough slots remain
 for 'num_descs'.
Reserves space in this IOAT descriptor ring by ensuring enough slots remain for ' num_descs ' .