Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4ce01c51 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of git://git.kernel.dk/linux-block

Pull block layer fixes from Jens Axboe:
 "A round of fixes/updates for the current series.

  This looks a little bigger than it is, but that's mainly because we
  pushed the lightnvm enabled null_blk change out of the merge window so
  it could be updated a bit.  The rest of the volume is also mostly
  lightnvm.  In particular:

   - Lightnvm.  Various fixes, additions, updates from Matias and
     Javier, as well as from Wenwei Tao.

   - NVMe:
        - Fix for potential arithmetic overflow from Keith.
        - Also from Keith, ensure that we reap pending completions from
          a completion queue before deleting it.  Fixes kernel crashes
          when resetting a device with IO pending.
        - Various little lightnvm related tweaks from Matias.

   - Fixup flushes to go through the IO scheduler, for the cases where a
     flush is not required.  Fixes a case in CFQ where we would be
     idling and not see this request, hence not break the idling.  From
     Jan Kara.

   - Use list_{first,prev,next} in elevator.c for cleaner code.  From
     Gelian Tang.

   - Fix for a warning trigger on btrfs and raid on single queue blk-mq
     devices, where we would flush plug callbacks with preemption
     disabled.  From me.

   - A mac partition validation fix from Kees Cook.

   - Two merge fixes from Ming, marked stable.  A third part is adding a
     new warning so we'll notice this quicker in the future, if we screw
     up the accounting.

   - Cleanup of thread name/creation in mtip32xx from Rasmus Villemoes"

* 'for-linus' of git://git.kernel.dk/linux-block: (32 commits)
  blk-merge: warn if figured out segment number is bigger than nr_phys_segments
  blk-merge: fix blk_bio_segment_split
  block: fix segment split
  blk-mq: fix calling unplug callbacks with preempt disabled
  mac: validate mac_partition is within sector
  mtip32xx: use formatting capability of kthread_create_on_node
  NVMe: reap completion entries when deleting queue
  lightnvm: add free and bad lun info to show luns
  lightnvm: keep track of block counts
  nvme: lightnvm: use admin queues for admin cmds
  lightnvm: missing free on init error
  lightnvm: wrong return value and redundant free
  null_blk: do not del gendisk with lightnvm
  null_blk: use device addressing mode
  null_blk: use ppa_cache pool
  NVMe: Fix possible arithmetic overflow for max segments
  blk-flush: Queue through IO scheduler when flush not required
  null_blk: register as a LightNVM device
  elevator: use list_{first,prev,next}_entry
  lightnvm: cleanup queue before target removal
  ...
parents a2931547 12e57f59
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -70,3 +70,6 @@ use_per_node_hctx=[0/1]: Default: 0
     parameter.
  1: The multi-queue block layer is instantiated with a hardware dispatch
     queue for each CPU node in the system.

use_lightnvm=[0/1]: Default: 0
  Register device with LightNVM. Requires blk-mq to be used.
+1 −0
Original line number Diff line number Diff line
@@ -6366,6 +6366,7 @@ F: arch/*/include/asm/pmem.h
LIGHTNVM PLATFORM SUPPORT
M:	Matias Bjorling <mb@lightnvm.io>
W:	http://github/OpenChannelSSD
L:	linux-block@vger.kernel.org
S:	Maintained
F:	drivers/lightnvm/
F:	include/linux/lightnvm.h
+1 −1
Original line number Diff line number Diff line
@@ -422,7 +422,7 @@ void blk_insert_flush(struct request *rq)
		if (q->mq_ops) {
			blk_mq_insert_request(rq, false, false, true);
		} else
			list_add_tail(&rq->queuelist, &q->queue_head);
			q->elevator->type->ops.elevator_add_req_fn(q, rq);
		return;
	}

+27 −5
Original line number Diff line number Diff line
@@ -76,6 +76,9 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
	struct bio_vec bv, bvprv, *bvprvp = NULL;
	struct bvec_iter iter;
	unsigned seg_size = 0, nsegs = 0, sectors = 0;
	unsigned front_seg_size = bio->bi_seg_front_size;
	bool do_split = true;
	struct bio *new = NULL;

	bio_for_each_segment(bv, bio, iter) {
		if (sectors + (bv.bv_len >> 9) > queue_max_sectors(q))
@@ -98,7 +101,7 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,

			seg_size += bv.bv_len;
			bvprv = bv;
			bvprvp = &bv;
			bvprvp = &bvprv;
			sectors += bv.bv_len >> 9;
			continue;
		}
@@ -108,16 +111,29 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,

		nsegs++;
		bvprv = bv;
		bvprvp = &bv;
		bvprvp = &bvprv;
		seg_size = bv.bv_len;
		sectors += bv.bv_len >> 9;

		if (nsegs == 1 && seg_size > front_seg_size)
			front_seg_size = seg_size;
	}

	*segs = nsegs;
	return NULL;
	do_split = false;
split:
	*segs = nsegs;
	return bio_split(bio, sectors, GFP_NOIO, bs);

	if (do_split) {
		new = bio_split(bio, sectors, GFP_NOIO, bs);
		if (new)
			bio = new;
	}

	bio->bi_seg_front_size = front_seg_size;
	if (seg_size > bio->bi_seg_back_size)
		bio->bi_seg_back_size = seg_size;

	return do_split ? new : NULL;
}

void blk_queue_split(struct request_queue *q, struct bio **bio,
@@ -412,6 +428,12 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
	if (sg)
		sg_mark_end(sg);

	/*
	 * Something must have been wrong if the figured number of
	 * segment is bigger than number of req's physical segments
	 */
	WARN_ON(nsegs > rq->nr_phys_segments);

	return nsegs;
}
EXPORT_SYMBOL(blk_rq_map_sg);
+9 −5
Original line number Diff line number Diff line
@@ -1291,15 +1291,16 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
		blk_mq_bio_to_request(rq, bio);

		/*
		 * we do limited pluging. If bio can be merged, do merge.
		 * We do limited pluging. If the bio can be merged, do that.
		 * Otherwise the existing request in the plug list will be
		 * issued. So the plug list will have one request at most
		 */
		if (plug) {
			/*
			 * The plug list might get flushed before this. If that
			 * happens, same_queue_rq is invalid and plug list is empty
			 **/
			 * happens, same_queue_rq is invalid and plug list is
			 * empty
			 */
			if (same_queue_rq && !list_empty(&plug->mq_list)) {
				old_rq = same_queue_rq;
				list_del_init(&old_rq->queuelist);
@@ -1380,12 +1381,15 @@ static blk_qc_t blk_sq_make_request(struct request_queue *q, struct bio *bio)
		blk_mq_bio_to_request(rq, bio);
		if (!request_count)
			trace_block_plug(q);
		else if (request_count >= BLK_MAX_REQUEST_COUNT) {

		blk_mq_put_ctx(data.ctx);

		if (request_count >= BLK_MAX_REQUEST_COUNT) {
			blk_flush_plug_list(plug, false);
			trace_block_plug(q);
		}

		list_add_tail(&rq->queuelist, &plug->mq_list);
		blk_mq_put_ctx(data.ctx);
		return cookie;
	}

Loading