staticinlinevoid bio_get_last_bvec(struct bio *bio, struct bio_vec *bv)
{ struct bvec_iter iter = bio->bi_iter; int idx;
bio_get_first_bvec(bio, bv); if (bv->bv_len == bio->bi_iter.bi_size) return; /* this bio only has a single bvec */
bio_advance_iter(bio, &iter, iter.bi_size);
if (!iter.bi_bvec_done)
idx = iter.bi_idx - 1; else/* in the middle of bvec */
idx = iter.bi_idx;
*bv = bio->bi_io_vec[idx];
/* * iter.bi_bvec_done records actual length of the last bvec * if this bio ends in the middle of one io vector
*/ if (iter.bi_bvec_done)
bv->bv_len = iter.bi_bvec_done;
}
staticinlinebool bio_will_gap(struct request_queue *q, struct request *prev_rq, struct bio *prev, struct bio *next)
{ struct bio_vec pb, nb;
if (!bio_has_data(prev) || !queue_virt_boundary(q)) returnfalse;
/* * Don't merge if the 1st bio starts with non-zero offset, otherwise it * is quite difficult to respect the sg gap limit. We work hard to * merge a huge number of small single bios in case of mkfs.
*/ if (prev_rq)
bio_get_first_bvec(prev_rq->bio, &pb); else
bio_get_first_bvec(prev, &pb); if (pb.bv_offset & queue_virt_boundary(q)) returntrue;
/* * We don't need to worry about the situation that the merged segment * ends in unaligned virt boundary: * * - if 'pb' ends aligned, the merged segment ends aligned * - if 'pb' ends unaligned, the next bio must include * one single bvec of 'nb', otherwise the 'nb' can't * merge with 'pb'
*/
bio_get_last_bvec(prev, &pb);
bio_get_first_bvec(next, &nb); if (biovec_phys_mergeable(q, &pb, &nb)) returnfalse; return __bvec_gap_to_prev(&q->limits, &pb, nb.bv_offset);
}
/* * The max size one bio can handle is UINT_MAX becasue bvec_iter.bi_size * is defined as 'unsigned int', meantime it has to be aligned to with the * logical block size, which is the minimum accepted unit by hardware.
*/ staticunsignedint bio_allowed_max_sectors(conststruct queue_limits *lim)
{ return round_down(UINT_MAX, lim->logical_block_size) >> SECTOR_SHIFT;
}
/* * bio_submit_split_bioset - Submit a bio, splitting it at a designated sector * @bio: the original bio to be submitted and split * @split_sectors: the sector count at which to split * @bs: the bio set used for allocating the new split bio * * The original bio is modified to contain the remaining sectors and submitted. * The caller is responsible for submitting the returned bio. * * If succeed, the newly allocated bio representing the initial part will be * returned, on failure NULL will be returned and original bio will fail.
*/ struct bio *bio_submit_split_bioset(struct bio *bio, unsignedint split_sectors, struct bio_set *bs)
{ struct bio *split = bio_split(bio, split_sectors, GFP_NOIO, bs);
if (IS_ERR(split)) {
bio->bi_status = errno_to_blk_status(PTR_ERR(split));
bio_endio(bio); return NULL;
}
staticstruct bio *bio_submit_split(struct bio *bio, int split_sectors)
{ if (unlikely(split_sectors < 0)) {
bio->bi_status = errno_to_blk_status(split_sectors);
bio_endio(bio); return NULL;
}
if (split_sectors) {
bio = bio_submit_split_bioset(bio, split_sectors,
&bio->bi_bdev->bd_disk->bio_split); if (bio)
bio->bi_opf |= REQ_NOMERGE;
}
return bio;
}
struct bio *bio_split_discard(struct bio *bio, conststruct queue_limits *lim, unsigned *nsegs)
{ unsignedint max_discard_sectors, granularity;
sector_t tmp; unsigned split_sectors;
if (bio_sectors(bio) <= max_discard_sectors) return bio;
split_sectors = max_discard_sectors;
/* * If the next starting sector would be misaligned, stop the discard at * the previous aligned sector.
*/
tmp = bio->bi_iter.bi_sector + split_sectors -
((lim->discard_alignment >> 9) % granularity);
tmp = sector_div(tmp, granularity);
if (split_sectors > tmp)
split_sectors -= tmp;
return bio_submit_split(bio, split_sectors);
}
staticinlineunsignedint blk_boundary_sectors(conststruct queue_limits *lim, bool is_atomic)
{ /* * chunk_sectors must be a multiple of atomic_write_boundary_sectors if * both non-zero.
*/ if (is_atomic && lim->atomic_write_boundary_sectors) return lim->atomic_write_boundary_sectors;
return lim->chunk_sectors;
}
/* * Return the maximum number of sectors from the start of a bio that may be * submitted as a single request to a block device. If enough sectors remain, * align the end to the physical block size. Otherwise align the end to the * logical block size. This approach minimizes the number of non-aligned * requests that are submitted to a block device if the start of a bio is not * aligned to a physical block boundary.
*/ staticinlineunsigned get_max_io_size(struct bio *bio, conststruct queue_limits *lim)
{ unsigned pbs = lim->physical_block_size >> SECTOR_SHIFT; unsigned lbs = lim->logical_block_size >> SECTOR_SHIFT; bool is_atomic = bio->bi_opf & REQ_ATOMIC; unsigned boundary_sectors = blk_boundary_sectors(lim, is_atomic); unsigned max_sectors, start, end;
/* * We ignore lim->max_sectors for atomic writes because it may less * than the actual bio size, which we cannot tolerate.
*/ if (bio_op(bio) == REQ_OP_WRITE_ZEROES)
max_sectors = lim->max_write_zeroes_sectors; elseif (is_atomic)
max_sectors = lim->atomic_write_max_sectors; else
max_sectors = lim->max_sectors;
if (boundary_sectors) {
max_sectors = min(max_sectors,
blk_boundary_sectors_left(bio->bi_iter.bi_sector,
boundary_sectors));
}
/** * bvec_split_segs - verify whether or not a bvec should be split in the middle * @lim: [in] queue limits to split based on * @bv: [in] bvec to examine * @nsegs: [in,out] Number of segments in the bio being built. Incremented * by the number of segments from @bv that may be appended to that * bio without exceeding @max_segs * @bytes: [in,out] Number of bytes in the bio being built. Incremented * by the number of bytes from @bv that may be appended to that * bio without exceeding @max_bytes * @max_segs: [in] upper bound for *@nsegs * @max_bytes: [in] upper bound for *@bytes * * When splitting a bio, it can happen that a bvec is encountered that is too * big to fit in a single segment and hence that it has to be split in the * middle. This function verifies whether or not that should happen. The value * %true is returned if and only if appending the entire @bv to a bio with * *@nsegs segments and *@sectors sectors would make that bio unacceptable for * the block driver.
*/ staticbool bvec_split_segs(conststruct queue_limits *lim, conststruct bio_vec *bv, unsigned *nsegs, unsigned *bytes, unsigned max_segs, unsigned max_bytes)
{ unsigned max_len = max_bytes - *bytes; unsigned len = min(bv->bv_len, max_len); unsigned total_len = 0; unsigned seg_size = 0;
(*nsegs)++;
total_len += seg_size;
len -= seg_size;
if ((bv->bv_offset + total_len) & lim->virt_boundary_mask) break;
}
*bytes += total_len;
/* tell the caller to split the bvec if it is too big to fit */ return len > 0 || bv->bv_len > max_len;
}
staticunsignedint bio_split_alignment(struct bio *bio, conststruct queue_limits *lim)
{ if (op_is_write(bio_op(bio)) && lim->zone_write_granularity) return lim->zone_write_granularity; return lim->logical_block_size;
}
/** * bio_split_io_at - check if and where to split a bio * @bio: [in] bio to be split * @lim: [in] queue limits to split based on * @segs: [out] number of segments in the bio with the first half of the sectors * @max_bytes: [in] maximum number of bytes per bio * @len_align_mask: [in] length alignment mask for each vector * * Find out if @bio needs to be split to fit the queue limits in @lim and a * maximum size of @max_bytes. Returns a negative error number if @bio can't be * split, 0 if the bio doesn't have to be split, or a positive sector offset if * @bio needs to be split.
*/ int bio_split_io_at(struct bio *bio, conststruct queue_limits *lim, unsigned *segs, unsigned max_bytes, unsigned len_align_mask)
{ struct bio_vec bv, bvprv, *bvprvp = NULL; struct bvec_iter iter; unsigned nsegs = 0, bytes = 0;
/* * If the queue doesn't support SG gaps and adding this * offset would create a gap, disallow it.
*/ if (bvprvp && bvec_gap_to_prev(lim, bvprvp, bv.bv_offset)) goto split;
/* * We can't sanely support splitting for a REQ_NOWAIT bio. End it * with EAGAIN if splitting is required and return an error pointer.
*/ if (bio->bi_opf & REQ_NOWAIT) return -EAGAIN;
*segs = nsegs;
/* * Individual bvecs might not be logical block aligned. Round down the * split size so that each bio is properly block size aligned, even if * we do not use the full hardware limits. * * It is possible to submit a bio that can't be split into a valid io: * there may either be too many discontiguous vectors for the max * segments limit, or contain virtual boundary gaps without having a * valid block sized split. A zero byte result means one of those * conditions occured.
*/
bytes = ALIGN_DOWN(bytes, bio_split_alignment(bio, lim)); if (!bytes) return -EINVAL;
/* * Bio splitting may cause subtle trouble such as hang when doing sync * iopoll in direct IO routine. Given performance gain of iopoll for * big IO can be trival, disable iopoll when split needed.
*/
bio_clear_polled(bio); return bytes >> SECTOR_SHIFT;
}
EXPORT_SYMBOL_GPL(bio_split_io_at);
/* * REQ_OP_ZONE_APPEND bios must never be split by the block layer. * * But we want the nr_segs calculation provided by bio_split_rw_at, and having * a good sanity check that the submitter built the bio correctly is nice to * have as well.
*/ struct bio *bio_split_zone_append(struct bio *bio, conststruct queue_limits *lim, unsigned *nr_segs)
{ int split_sectors;
struct bio *bio_split_write_zeroes(struct bio *bio, conststruct queue_limits *lim, unsigned *nsegs)
{ unsignedint max_sectors = get_max_io_size(bio, lim);
*nsegs = 0;
/* * An unset limit should normally not happen, as bio submission is keyed * off having a non-zero limit. But SCSI can clear the limit in the * I/O completion handler, and we can race and see this. Splitting to a * zero limit obviously doesn't make sense, so band-aid it here.
*/ if (!max_sectors) return bio; if (bio_sectors(bio) <= max_sectors) return bio; return bio_submit_split(bio, max_sectors);
}
/** * bio_split_to_limits - split a bio to fit the queue limits * @bio: bio to be split * * Check if @bio needs splitting based on the queue limits of @bio->bi_bdev, and * if so split off a bio fitting the limits from the beginning of @bio and * return it. @bio is shortened to the remainder and re-submitted. * * The split bio is allocated from @q->bio_split, which is provided by the * block layer.
*/ struct bio *bio_split_to_limits(struct bio *bio)
{ unsignedint nr_segs;
staticinlineint ll_new_hw_segment(struct request *req, struct bio *bio, unsignedint nr_phys_segs)
{ if (!blk_cgroup_mergeable(req, bio)) goto no_merge;
if (blk_integrity_merge_bio(req->q, req, bio) == false) goto no_merge;
/* discard request merge won't add new segment */ if (req_op(req) == REQ_OP_DISCARD) return 1;
if (req->nr_phys_segments + nr_phys_segs > blk_rq_get_max_segments(req)) goto no_merge;
/* * This will form the start of a new hw segment. Bump both * counters.
*/
req->nr_phys_segments += nr_phys_segs; if (bio_integrity(bio))
req->nr_integrity_segments += blk_rq_count_integrity_sg(req->q,
bio); return 1;
/** * blk_rq_set_mixed_merge - mark a request as mixed merge * @rq: request to mark as mixed merge * * Description: * @rq is about to be mixed merged. Make sure the attributes * which can be mixed are set in each bio and mark @rq as mixed * merged.
*/ staticvoid blk_rq_set_mixed_merge(struct request *rq)
{
blk_opf_t ff = rq->cmd_flags & REQ_FAILFAST_MASK; struct bio *bio;
if (rq->rq_flags & RQF_MIXED_MERGE) return;
/* * @rq will no longer represent mixable attributes for all the * contained bios. It will just track those of the first one. * Distributes the attributs to each bio.
*/ for (bio = rq->bio; bio; bio = bio->bi_next) {
WARN_ON_ONCE((bio->bi_opf & REQ_FAILFAST_MASK) &&
(bio->bi_opf & REQ_FAILFAST_MASK) != ff);
bio->bi_opf |= ff;
}
rq->rq_flags |= RQF_MIXED_MERGE;
}
staticinline blk_opf_t bio_failfast(conststruct bio *bio)
{ if (bio->bi_opf & REQ_RAHEAD) return REQ_FAILFAST_MASK;
return bio->bi_opf & REQ_FAILFAST_MASK;
}
/* * After we are marked as MIXED_MERGE, any new RA bio has to be updated * as failfast, and request's failfast has to be updated in case of * front merge.
*/ staticinlinevoid blk_update_mixed_merge(struct request *req, struct bio *bio, bool front_merge)
{ if (req->rq_flags & RQF_MIXED_MERGE) { if (bio->bi_opf & REQ_RAHEAD)
bio->bi_opf |= REQ_FAILFAST_MASK;
/* * For non-mq, this has to be called with the request spinlock acquired. * For mq with scheduling, the appropriate queue wide lock should be held.
*/ staticstruct request *attempt_merge(struct request_queue *q, struct request *req, struct request *next)
{ if (!rq_mergeable(req) || !rq_mergeable(next)) return NULL;
if (req_op(req) != req_op(next)) return NULL;
if (req->bio->bi_write_hint != next->bio->bi_write_hint) return NULL; if (req->bio->bi_write_stream != next->bio->bi_write_stream) return NULL; if (req->bio->bi_ioprio != next->bio->bi_ioprio) return NULL; if (!blk_atomic_write_mergeable_rqs(req, next)) return NULL;
/* * If we are allowed to merge, then append bio list * from next to rq and release next. merge_requests_fn * will have updated segment counts, update sector * counts here. Handle DISCARDs separately, as they * have separate settings.
*/
switch (blk_try_req_merge(req, next)) { case ELEVATOR_DISCARD_MERGE: if (!req_attempt_discard_merge(q, req, next)) return NULL; break; case ELEVATOR_BACK_MERGE: if (!ll_merge_requests_fn(q, req, next)) return NULL; break; default: return NULL;
}
/* * If failfast settings disagree or any of the two is already * a mixed merge, mark both as mixed before proceeding. This * makes sure that all involved bios have mixable attributes * set properly.
*/ if (((req->rq_flags | next->rq_flags) & RQF_MIXED_MERGE) ||
(req->cmd_flags & REQ_FAILFAST_MASK) !=
(next->cmd_flags & REQ_FAILFAST_MASK)) {
blk_rq_set_mixed_merge(req);
blk_rq_set_mixed_merge(next);
}
/* * At this point we have either done a back merge or front merge. We * need the smaller start_time_ns of the merged requests to be the * current request for accounting purposes.
*/ if (next->start_time_ns < req->start_time_ns)
req->start_time_ns = next->start_time_ns;
/* * A front merge for writes to sequential zones of a zoned block device * can happen only if the user submitted writes out of order. Do not * merge such write to let it fail.
*/ if (req->rq_flags & RQF_ZONE_WRITE_PLUGGING) return BIO_MERGE_FAILED;
if (!ll_front_merge_fn(req, bio, nr_segs)) return BIO_MERGE_FAILED;
switch (blk_try_merge(rq, bio)) { case ELEVATOR_BACK_MERGE: if (!sched_allow_merge || blk_mq_sched_allow_merge(q, rq, bio)) return bio_attempt_back_merge(rq, bio, nr_segs); break; case ELEVATOR_FRONT_MERGE: if (!sched_allow_merge || blk_mq_sched_allow_merge(q, rq, bio)) return bio_attempt_front_merge(rq, bio, nr_segs); break; case ELEVATOR_DISCARD_MERGE: return bio_attempt_discard_merge(q, rq, bio); default: return BIO_MERGE_NONE;
}
return BIO_MERGE_FAILED;
}
/** * blk_attempt_plug_merge - try to merge with %current's plugged list * @q: request_queue new bio is being queued at * @bio: new bio being queued * @nr_segs: number of segments in @bio * from the passed in @q already in the plug list * * Determine whether @bio being queued on @q can be merged with the previous * request on %current's plugged list. Returns %true if merge was successful, * otherwise %false. * * Plugging coalesces IOs from the same issuer for the same purpose without * going through @q->queue_lock. As such it's more of an issuing mechanism * than scheduling, and the request, while may have elvpriv data, is not * added on the elevator at this point. In addition, we don't have * reliable access to the elevator outside queue lock. Only check basic * merging parameters without querying the elevator. * * Caller must ensure !blk_queue_nomerges(q) beforehand.
*/ bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio, unsignedint nr_segs)
{ struct blk_plug *plug = current->plug; struct request *rq;
if (!plug || rq_list_empty(&plug->mq_list)) returnfalse;
/* * Iterate list of requests and see if we can merge this bio with any * of them.
*/ bool blk_bio_list_merge(struct request_queue *q, struct list_head *list, struct bio *bio, unsignedint nr_segs)
{ struct request *rq; int checked = 8;
list_for_each_entry_reverse(rq, list, queuelist) { if (!checked--) break;
switch (blk_attempt_bio_merge(q, rq, bio, nr_segs, true)) { case BIO_MERGE_NONE: continue; case BIO_MERGE_OK: returntrue; case BIO_MERGE_FAILED: returnfalse;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.