mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
Merge branch 'for-linus' of git://git.kernel.dk/linux-block
Pull block layer fixes from Jens Axboe: "Four small fixes that should be merged for the current 3.18-rc series. This pull request contains: - a minor bugfix for computation of best IO priority given two merging requests. From Jan Kara. - the final (final) merge count issue that has been plaguing virtio-blk. From Ming Lei. - enable parallel reinit notify for blk-mq queues, to combine the cost of an RCU grace period across lots of devices. From Tejun Heo. - an error handling fix for the SCSI_IOCTL_SEND_COMMAND ioctl. From Tony Battersby" * 'for-linus' of git://git.kernel.dk/linux-block: block: blk-merge: fix blk_recount_segments() scsi: Fix more error handling in SCSI_IOCTL_SEND_COMMAND blk-mq: make mq_queue_reinit_notify() freeze queues in parallel block: Fix computation of merged request priority
This commit is contained in:
commit
6f0d7a9eb6
@ -97,19 +97,22 @@ void blk_recalc_rq_segments(struct request *rq)
|
|||||||
|
|
||||||
void blk_recount_segments(struct request_queue *q, struct bio *bio)
|
void blk_recount_segments(struct request_queue *q, struct bio *bio)
|
||||||
{
|
{
|
||||||
bool no_sg_merge = !!test_bit(QUEUE_FLAG_NO_SG_MERGE,
|
unsigned short seg_cnt;
|
||||||
&q->queue_flags);
|
|
||||||
bool merge_not_need = bio->bi_vcnt < queue_max_segments(q);
|
|
||||||
|
|
||||||
if (no_sg_merge && !bio_flagged(bio, BIO_CLONED) &&
|
/* estimate segment number by bi_vcnt for non-cloned bio */
|
||||||
merge_not_need)
|
if (bio_flagged(bio, BIO_CLONED))
|
||||||
bio->bi_phys_segments = bio->bi_vcnt;
|
seg_cnt = bio_segments(bio);
|
||||||
|
else
|
||||||
|
seg_cnt = bio->bi_vcnt;
|
||||||
|
|
||||||
|
if (test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags) &&
|
||||||
|
(seg_cnt < queue_max_segments(q)))
|
||||||
|
bio->bi_phys_segments = seg_cnt;
|
||||||
else {
|
else {
|
||||||
struct bio *nxt = bio->bi_next;
|
struct bio *nxt = bio->bi_next;
|
||||||
|
|
||||||
bio->bi_next = NULL;
|
bio->bi_next = NULL;
|
||||||
bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio,
|
bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, false);
|
||||||
no_sg_merge && merge_not_need);
|
|
||||||
bio->bi_next = nxt;
|
bio->bi_next = nxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,11 +107,7 @@ static void blk_mq_usage_counter_release(struct percpu_ref *ref)
|
|||||||
wake_up_all(&q->mq_freeze_wq);
|
wake_up_all(&q->mq_freeze_wq);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static void blk_mq_freeze_queue_start(struct request_queue *q)
|
||||||
* Guarantee no request is in use, so we can change any data structure of
|
|
||||||
* the queue afterward.
|
|
||||||
*/
|
|
||||||
void blk_mq_freeze_queue(struct request_queue *q)
|
|
||||||
{
|
{
|
||||||
bool freeze;
|
bool freeze;
|
||||||
|
|
||||||
@ -123,9 +119,23 @@ void blk_mq_freeze_queue(struct request_queue *q)
|
|||||||
percpu_ref_kill(&q->mq_usage_counter);
|
percpu_ref_kill(&q->mq_usage_counter);
|
||||||
blk_mq_run_queues(q, false);
|
blk_mq_run_queues(q, false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void blk_mq_freeze_queue_wait(struct request_queue *q)
|
||||||
|
{
|
||||||
wait_event(q->mq_freeze_wq, percpu_ref_is_zero(&q->mq_usage_counter));
|
wait_event(q->mq_freeze_wq, percpu_ref_is_zero(&q->mq_usage_counter));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Guarantee no request is in use, so we can change any data structure of
|
||||||
|
* the queue afterward.
|
||||||
|
*/
|
||||||
|
void blk_mq_freeze_queue(struct request_queue *q)
|
||||||
|
{
|
||||||
|
blk_mq_freeze_queue_start(q);
|
||||||
|
blk_mq_freeze_queue_wait(q);
|
||||||
|
}
|
||||||
|
|
||||||
static void blk_mq_unfreeze_queue(struct request_queue *q)
|
static void blk_mq_unfreeze_queue(struct request_queue *q)
|
||||||
{
|
{
|
||||||
bool wake;
|
bool wake;
|
||||||
@ -1921,7 +1931,7 @@ void blk_mq_free_queue(struct request_queue *q)
|
|||||||
/* Basically redo blk_mq_init_queue with queue frozen */
|
/* Basically redo blk_mq_init_queue with queue frozen */
|
||||||
static void blk_mq_queue_reinit(struct request_queue *q)
|
static void blk_mq_queue_reinit(struct request_queue *q)
|
||||||
{
|
{
|
||||||
blk_mq_freeze_queue(q);
|
WARN_ON_ONCE(!q->mq_freeze_depth);
|
||||||
|
|
||||||
blk_mq_sysfs_unregister(q);
|
blk_mq_sysfs_unregister(q);
|
||||||
|
|
||||||
@ -1936,8 +1946,6 @@ static void blk_mq_queue_reinit(struct request_queue *q)
|
|||||||
blk_mq_map_swqueue(q);
|
blk_mq_map_swqueue(q);
|
||||||
|
|
||||||
blk_mq_sysfs_register(q);
|
blk_mq_sysfs_register(q);
|
||||||
|
|
||||||
blk_mq_unfreeze_queue(q);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int blk_mq_queue_reinit_notify(struct notifier_block *nb,
|
static int blk_mq_queue_reinit_notify(struct notifier_block *nb,
|
||||||
@ -1956,8 +1964,25 @@ static int blk_mq_queue_reinit_notify(struct notifier_block *nb,
|
|||||||
return NOTIFY_OK;
|
return NOTIFY_OK;
|
||||||
|
|
||||||
mutex_lock(&all_q_mutex);
|
mutex_lock(&all_q_mutex);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to freeze and reinit all existing queues. Freezing
|
||||||
|
* involves synchronous wait for an RCU grace period and doing it
|
||||||
|
* one by one may take a long time. Start freezing all queues in
|
||||||
|
* one swoop and then wait for the completions so that freezing can
|
||||||
|
* take place in parallel.
|
||||||
|
*/
|
||||||
|
list_for_each_entry(q, &all_q_list, all_q_node)
|
||||||
|
blk_mq_freeze_queue_start(q);
|
||||||
|
list_for_each_entry(q, &all_q_list, all_q_node)
|
||||||
|
blk_mq_freeze_queue_wait(q);
|
||||||
|
|
||||||
list_for_each_entry(q, &all_q_list, all_q_node)
|
list_for_each_entry(q, &all_q_list, all_q_node)
|
||||||
blk_mq_queue_reinit(q);
|
blk_mq_queue_reinit(q);
|
||||||
|
|
||||||
|
list_for_each_entry(q, &all_q_list, all_q_node)
|
||||||
|
blk_mq_unfreeze_queue(q);
|
||||||
|
|
||||||
mutex_unlock(&all_q_mutex);
|
mutex_unlock(&all_q_mutex);
|
||||||
return NOTIFY_OK;
|
return NOTIFY_OK;
|
||||||
}
|
}
|
||||||
|
@ -157,14 +157,16 @@ out:
|
|||||||
|
|
||||||
int ioprio_best(unsigned short aprio, unsigned short bprio)
|
int ioprio_best(unsigned short aprio, unsigned short bprio)
|
||||||
{
|
{
|
||||||
unsigned short aclass = IOPRIO_PRIO_CLASS(aprio);
|
unsigned short aclass;
|
||||||
unsigned short bclass = IOPRIO_PRIO_CLASS(bprio);
|
unsigned short bclass;
|
||||||
|
|
||||||
if (aclass == IOPRIO_CLASS_NONE)
|
if (!ioprio_valid(aprio))
|
||||||
aclass = IOPRIO_CLASS_BE;
|
aprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, IOPRIO_NORM);
|
||||||
if (bclass == IOPRIO_CLASS_NONE)
|
if (!ioprio_valid(bprio))
|
||||||
bclass = IOPRIO_CLASS_BE;
|
bprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, IOPRIO_NORM);
|
||||||
|
|
||||||
|
aclass = IOPRIO_PRIO_CLASS(aprio);
|
||||||
|
bclass = IOPRIO_PRIO_CLASS(bprio);
|
||||||
if (aclass == bclass)
|
if (aclass == bclass)
|
||||||
return min(aprio, bprio);
|
return min(aprio, bprio);
|
||||||
if (aclass > bclass)
|
if (aclass > bclass)
|
||||||
|
@ -458,7 +458,7 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
|
|||||||
rq = blk_get_request(q, in_len ? WRITE : READ, __GFP_WAIT);
|
rq = blk_get_request(q, in_len ? WRITE : READ, __GFP_WAIT);
|
||||||
if (IS_ERR(rq)) {
|
if (IS_ERR(rq)) {
|
||||||
err = PTR_ERR(rq);
|
err = PTR_ERR(rq);
|
||||||
goto error;
|
goto error_free_buffer;
|
||||||
}
|
}
|
||||||
blk_rq_set_block_pc(rq);
|
blk_rq_set_block_pc(rq);
|
||||||
|
|
||||||
@ -531,9 +531,11 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
kfree(buffer);
|
|
||||||
if (rq)
|
|
||||||
blk_put_request(rq);
|
blk_put_request(rq);
|
||||||
|
|
||||||
|
error_free_buffer:
|
||||||
|
kfree(buffer);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(sg_scsi_ioctl);
|
EXPORT_SYMBOL_GPL(sg_scsi_ioctl);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user