FreeBSD/sys/cam/cam_iosched.c
/*
 * Determine what the next bit of work to do is for the periph. The
 * default implementation looks to see if we have trims to do, but no
 * trims outstanding. If so, we do that. Otherwise we see if we have
 * other work. If we do, then we do that. Otherwise why were we called?
 */
Determine what the next bit of work to do is for the periph. The
default implementation looks to see if we have trims to do, but no
trims outstanding. If so, we do that. Otherwise we see if we have
other work. If we do, then we do that.
Determine what the next bit of work to do is for the periph . The default implementation looks to see if we have trims to do but no trims outstanding . If so we do that . Otherwise we see if we have other work . If we do then we do that .
struct bio *
cam_iosched_next_bio(struct cam_iosched_softc *isc)
{
	struct bio *bp;
	if ((bp = cam_iosched_get_trim(isc)) != NULL)
		return bp;
#ifdef CAM_IOSCHED_DYNAMIC
	if (do_dynamic_iosched) {
		if ((bp = cam_iosched_get_write(isc)) != NULL)
			return bp;
	}
#endif
	if ((bp = bioq_first(&isc->bio_queue)) == NULL)
		return NULL;
#ifdef CAM_IOSCHED_DYNAMIC
	if (do_dynamic_iosched) {
		if (bp->bio_cmd == BIO_READ &&
		    cam_iosched_limiter_iop(&isc->read_stats, bp) != 0)
			return NULL;
	}
#endif
	bioq_remove(&isc->bio_queue, bp);
#ifdef CAM_IOSCHED_DYNAMIC
	if (do_dynamic_iosched) {
		if (bp->bio_cmd == BIO_READ) {
			isc->read_stats.queued--;
			isc->read_stats.total++;
			isc->read_stats.pending++;
		} else
			printf("Found bio_cmd = %#x\n", bp->bio_cmd);
	}
	if (iosched_debug > 9)
		printf("HWQ : %p %#x\n", bp, bp->bio_cmd);
#endif
	return bp;
}
struct bio * cam_iosched_next_bio ( struct cam_iosched_softc * isc ) { struct bio * bp ; if ( ( bp = cam_iosched_get_trim ( isc ) ) != NULL ) return bp ; #ifdef CAM_IOSCHED_DYNAMIC if ( do_dynamic_iosched ) { if ( ( bp = cam_iosched_get_write ( isc ) ) != NULL ) return bp ; } #endif if ( ( bp = bioq_first ( & isc -> bio_queue ) ) == NULL ) return NULL ; #ifdef CAM_IOSCHED_DYNAMIC if ( do_dynamic_iosched ) { if ( bp -> bio_cmd == BIO_READ && cam_iosched_limiter_iop ( & isc -> read_stats , bp ) != 0 ) return NULL ; } #endif bioq_remove ( & isc -> bio_queue , bp ) ; #ifdef CAM_IOSCHED_DYNAMIC if ( do_dynamic_iosched ) { if ( bp -> bio_cmd == BIO_READ ) { isc -> read_stats . queued -- ; isc -> read_stats . total ++ ; isc -> read_stats . pending ++ ; } else printf ( " \n " , bp -> bio_cmd ) ; } if ( iosched_debug > 9 ) printf ( " \n " , bp , bp -> bio_cmd ) ; #endif return bp ; }
Determine what the next bit of work to do is for the periph.
Determine what the next bit of work to do is for the periph .
/*
	 * See if we have a trim that can be scheduled. We can only send one
	 * at a time down, so this takes that into account.
	 *
	 * XXX newer TRIM commands are queueable. Revisit this when we
	 * implement them.
	 */ /*
	 * See if we have any pending writes, and room in the queue for them,
	 * and if so, those are next.
	 */ /*
	 * next, see if there's other, normal I/O waiting. If so return that.
	 */ /*
	 * For the netflix scheduler, bio_queue is only for reads, so enforce
	 * the limits here. Enforce only for reads.
	 */