Skip to content

Commit

Permalink
Merge branch 'for-3.15/core' of git://git.kernel.dk/linux-block
Browse files Browse the repository at this point in the history
Pull core block layer updates from Jens Axboe:
 "This is the pull request for the core block IO bits for the 3.15
  kernel.  It's a smaller round this time, it contains:

   - Various little blk-mq fixes and additions from Christoph and
     myself.

   - Cleanup of the IPI usage from the block layer, and associated
     helper code.  From Frederic Weisbecker and Jan Kara.

   - Duplicate code cleanup in bio-integrity from Gu Zheng.  This will
     give you a merge conflict, but that should be easy to resolve.

   - blk-mq notify spinlock fix for RT from Mike Galbraith.

   - A blktrace partial accounting bug fix from Roman Pen.

   - Missing REQ_SYNC detection fix for blk-mq from Shaohua Li"

* 'for-3.15/core' of git://git.kernel.dk/linux-block: (25 commits)
  blk-mq: add REQ_SYNC early
  rt,blk,mq: Make blk_mq_cpu_notify_lock a raw spinlock
  blk-mq: support partial I/O completions
  blk-mq: merge blk_mq_insert_request and blk_mq_run_request
  blk-mq: remove blk_mq_alloc_rq
  blk-mq: don't dump CPU -> hw queue map on driver load
  blk-mq: fix wrong usage of hctx->state vs hctx->flags
  blk-mq: allow blk_mq_init_commands() to return failure
  block: remove old blk_iopoll_enabled variable
  blktrace: fix accounting of partially completed requests
  smp: Rename __smp_call_function_single() to smp_call_function_single_async()
  smp: Remove wait argument from __smp_call_function_single()
  watchdog: Simplify a little the IPI call
  smp: Move __smp_call_function_single() below its safe version
  smp: Consolidate the various smp_call_function_single() declensions
  smp: Teach __smp_call_function_single() to check for offline cpus
  smp: Remove unused list_head from csd
  smp: Iterate functions through llist_for_each_entry_safe()
  block: Stop abusing rq->csd.list in blk-softirq
  block: Remove useless IPI struct initialization
  ...
  • Loading branch information
torvalds committed Apr 2, 2014
2 parents 1a0b6ab + 27fbf4e commit 7a48837
Show file tree
Hide file tree
Showing 33 changed files with 352 additions and 378 deletions.
2 changes: 1 addition & 1 deletion block/blk-cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ static void blkg_destroy(struct blkcg_gq *blkg)
* under queue_lock. If it's not pointing to @blkg now, it never
* will. Hint assignment itself can race safely.
*/
if (rcu_dereference_raw(blkcg->blkg_hint) == blkg)
if (rcu_access_pointer(blkcg->blkg_hint) == blkg)
rcu_assign_pointer(blkcg->blkg_hint, NULL);

/*
Expand Down
2 changes: 1 addition & 1 deletion block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2353,7 +2353,7 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes)
if (!req->bio)
return false;

trace_block_rq_complete(req->q, req);
trace_block_rq_complete(req->q, req, nr_bytes);

/*
* For fs requests, rq is just carrier of independent bio's
Expand Down
2 changes: 1 addition & 1 deletion block/blk-ioc.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static void ioc_destroy_icq(struct io_cq *icq)
* under queue_lock. If it's not pointing to @icq now, it never
* will. Hint assignment itself can race safely.
*/
if (rcu_dereference_raw(ioc->icq_hint) == icq)
if (rcu_access_pointer(ioc->icq_hint) == icq)
rcu_assign_pointer(ioc->icq_hint, NULL);

ioc_exit_icq(icq);
Expand Down
3 changes: 0 additions & 3 deletions block/blk-iopoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@

#include "blk.h"

int blk_iopoll_enabled = 1;
EXPORT_SYMBOL(blk_iopoll_enabled);

static unsigned int blk_iopoll_budget __read_mostly = 256;

static DEFINE_PER_CPU(struct list_head, blk_cpu_iopoll);
Expand Down
10 changes: 0 additions & 10 deletions block/blk-mq-cpumap.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,6 @@
#include "blk.h"
#include "blk-mq.h"

static void show_map(unsigned int *map, unsigned int nr)
{
int i;

pr_info("blk-mq: CPU -> queue map\n");
for_each_online_cpu(i)
pr_info(" CPU%2u -> Queue %u\n", i, map[i]);
}

static int cpu_to_queue_index(unsigned int nr_cpus, unsigned int nr_queues,
const int cpu)
{
Expand Down Expand Up @@ -85,7 +76,6 @@ int blk_mq_update_queue_map(unsigned int *map, unsigned int nr_queues)
map[i] = map[first_sibling];
}

show_map(map, nr_cpus);
free_cpumask_var(cpus);
return 0;
}
Expand Down
31 changes: 31 additions & 0 deletions block/blk-mq-sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,32 @@ static ssize_t blk_mq_hw_sysfs_tags_show(struct blk_mq_hw_ctx *hctx, char *page)
return blk_mq_tag_sysfs_show(hctx->tags, page);
}

static ssize_t blk_mq_hw_sysfs_cpus_show(struct blk_mq_hw_ctx *hctx, char *page)
{
unsigned int i, queue_num, first = 1;
ssize_t ret = 0;

blk_mq_disable_hotplug();

for_each_online_cpu(i) {
queue_num = hctx->queue->mq_map[i];
if (queue_num != hctx->queue_num)
continue;

if (first)
ret += sprintf(ret + page, "%u", i);
else
ret += sprintf(ret + page, ", %u", i);

first = 0;
}

blk_mq_enable_hotplug();

ret += sprintf(ret + page, "\n");
return ret;
}

static struct blk_mq_ctx_sysfs_entry blk_mq_sysfs_dispatched = {
.attr = {.name = "dispatched", .mode = S_IRUGO },
.show = blk_mq_sysfs_dispatched_show,
Expand Down Expand Up @@ -294,6 +320,10 @@ static struct blk_mq_hw_ctx_sysfs_entry blk_mq_hw_sysfs_tags = {
.attr = {.name = "tags", .mode = S_IRUGO },
.show = blk_mq_hw_sysfs_tags_show,
};
static struct blk_mq_hw_ctx_sysfs_entry blk_mq_hw_sysfs_cpus = {
.attr = {.name = "cpu_list", .mode = S_IRUGO },
.show = blk_mq_hw_sysfs_cpus_show,
};

static struct attribute *default_hw_ctx_attrs[] = {
&blk_mq_hw_sysfs_queued.attr,
Expand All @@ -302,6 +332,7 @@ static struct attribute *default_hw_ctx_attrs[] = {
&blk_mq_hw_sysfs_pending.attr,
&blk_mq_hw_sysfs_ipi.attr,
&blk_mq_hw_sysfs_tags.attr,
&blk_mq_hw_sysfs_cpus.attr,
NULL,
};

Expand Down
70 changes: 59 additions & 11 deletions block/blk-mq.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ void __blk_mq_complete_request(struct request *rq)
rq->csd.func = __blk_mq_complete_request_remote;
rq->csd.info = rq;
rq->csd.flags = 0;
__smp_call_function_single(ctx->cpu, &rq->csd, 0);
smp_call_function_single_async(ctx->cpu, &rq->csd);
} else {
rq->q->softirq_done_fn(rq);
}
Expand Down Expand Up @@ -514,7 +514,7 @@ static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx)
LIST_HEAD(rq_list);
int bit, queued;

if (unlikely(test_bit(BLK_MQ_S_STOPPED, &hctx->flags)))
if (unlikely(test_bit(BLK_MQ_S_STOPPED, &hctx->state)))
return;

hctx->run++;
Expand Down Expand Up @@ -603,7 +603,7 @@ static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx)

void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async)
{
if (unlikely(test_bit(BLK_MQ_S_STOPPED, &hctx->flags)))
if (unlikely(test_bit(BLK_MQ_S_STOPPED, &hctx->state)))
return;

if (!async)
Expand All @@ -623,7 +623,7 @@ void blk_mq_run_queues(struct request_queue *q, bool async)
queue_for_each_hw_ctx(q, hctx, i) {
if ((!blk_mq_hctx_has_pending(hctx) &&
list_empty_careful(&hctx->dispatch)) ||
test_bit(BLK_MQ_S_STOPPED, &hctx->flags))
test_bit(BLK_MQ_S_STOPPED, &hctx->state))
continue;

blk_mq_run_hw_queue(hctx, async);
Expand Down Expand Up @@ -994,8 +994,46 @@ static void blk_mq_hctx_notify(void *data, unsigned long action,
blk_mq_put_ctx(ctx);
}

static void blk_mq_init_hw_commands(struct blk_mq_hw_ctx *hctx,
void (*init)(void *, struct blk_mq_hw_ctx *,
static int blk_mq_init_hw_commands(struct blk_mq_hw_ctx *hctx,
int (*init)(void *, struct blk_mq_hw_ctx *,
struct request *, unsigned int),
void *data)
{
unsigned int i;
int ret = 0;

for (i = 0; i < hctx->queue_depth; i++) {
struct request *rq = hctx->rqs[i];

ret = init(data, hctx, rq, i);
if (ret)
break;
}

return ret;
}

int blk_mq_init_commands(struct request_queue *q,
int (*init)(void *, struct blk_mq_hw_ctx *,
struct request *, unsigned int),
void *data)
{
struct blk_mq_hw_ctx *hctx;
unsigned int i;
int ret = 0;

queue_for_each_hw_ctx(q, hctx, i) {
ret = blk_mq_init_hw_commands(hctx, init, data);
if (ret)
break;
}

return ret;
}
EXPORT_SYMBOL(blk_mq_init_commands);

static void blk_mq_free_hw_commands(struct blk_mq_hw_ctx *hctx,
void (*free)(void *, struct blk_mq_hw_ctx *,
struct request *, unsigned int),
void *data)
{
Expand All @@ -1004,22 +1042,22 @@ static void blk_mq_init_hw_commands(struct blk_mq_hw_ctx *hctx,
for (i = 0; i < hctx->queue_depth; i++) {
struct request *rq = hctx->rqs[i];

init(data, hctx, rq, i);
free(data, hctx, rq, i);
}
}

void blk_mq_init_commands(struct request_queue *q,
void (*init)(void *, struct blk_mq_hw_ctx *,
void blk_mq_free_commands(struct request_queue *q,
void (*free)(void *, struct blk_mq_hw_ctx *,
struct request *, unsigned int),
void *data)
{
struct blk_mq_hw_ctx *hctx;
unsigned int i;

queue_for_each_hw_ctx(q, hctx, i)
blk_mq_init_hw_commands(hctx, init, data);
blk_mq_free_hw_commands(hctx, free, data);
}
EXPORT_SYMBOL(blk_mq_init_commands);
EXPORT_SYMBOL(blk_mq_free_commands);

static void blk_mq_free_rq_map(struct blk_mq_hw_ctx *hctx)
{
Expand Down Expand Up @@ -1430,6 +1468,16 @@ static int blk_mq_queue_reinit_notify(struct notifier_block *nb,
return NOTIFY_OK;
}

void blk_mq_disable_hotplug(void)
{
mutex_lock(&all_q_mutex);
}

void blk_mq_enable_hotplug(void)
{
mutex_unlock(&all_q_mutex);
}

static int __init blk_mq_init(void)
{
blk_mq_cpu_init();
Expand Down
2 changes: 2 additions & 0 deletions block/blk-mq.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ void blk_mq_init_cpu_notifier(struct blk_mq_cpu_notifier *notifier,
void blk_mq_register_cpu_notifier(struct blk_mq_cpu_notifier *notifier);
void blk_mq_unregister_cpu_notifier(struct blk_mq_cpu_notifier *notifier);
void blk_mq_cpu_init(void);
void blk_mq_enable_hotplug(void);
void blk_mq_disable_hotplug(void);

/*
* CPU -> queue mappings
Expand Down
19 changes: 12 additions & 7 deletions block/blk-softirq.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ static void blk_done_softirq(struct softirq_action *h)
while (!list_empty(&local_list)) {
struct request *rq;

rq = list_entry(local_list.next, struct request, csd.list);
list_del_init(&rq->csd.list);
rq = list_entry(local_list.next, struct request, queuelist);
list_del_init(&rq->queuelist);
rq->q->softirq_done_fn(rq);
}
}
Expand All @@ -45,9 +45,14 @@ static void trigger_softirq(void *data)

local_irq_save(flags);
list = this_cpu_ptr(&blk_cpu_done);
list_add_tail(&rq->csd.list, list);
/*
* We reuse queuelist for a list of requests to process. Since the
* queuelist is used by the block layer only for requests waiting to be
* submitted to the device it is unused now.
*/
list_add_tail(&rq->queuelist, list);

if (list->next == &rq->csd.list)
if (list->next == &rq->queuelist)
raise_softirq_irqoff(BLOCK_SOFTIRQ);

local_irq_restore(flags);
Expand All @@ -65,7 +70,7 @@ static int raise_blk_irq(int cpu, struct request *rq)
data->info = rq;
data->flags = 0;

__smp_call_function_single(cpu, data, 0);
smp_call_function_single_async(cpu, data);
return 0;
}

Expand Down Expand Up @@ -136,15 +141,15 @@ void __blk_complete_request(struct request *req)
struct list_head *list;
do_local:
list = this_cpu_ptr(&blk_cpu_done);
list_add_tail(&req->csd.list, list);
list_add_tail(&req->queuelist, list);

/*
* if the list only contains our just added request,
* signal a raise of the softirq. If there are already
* entries there, someone already raised the irq but it
* hasn't run yet.
*/
if (list->next == &req->csd.list)
if (list->next == &req->queuelist)
raise_softirq_irqoff(BLOCK_SOFTIRQ);
} else if (raise_blk_irq(ccpu, req))
goto do_local;
Expand Down
8 changes: 4 additions & 4 deletions block/cfq-iosched.c
Original file line number Diff line number Diff line change
Expand Up @@ -2367,10 +2367,10 @@ cfq_merged_requests(struct request_queue *q, struct request *rq,
* reposition in fifo if next is older than rq
*/
if (!list_empty(&rq->queuelist) && !list_empty(&next->queuelist) &&
time_before(rq_fifo_time(next), rq_fifo_time(rq)) &&
time_before(next->fifo_time, rq->fifo_time) &&
cfqq == RQ_CFQQ(next)) {
list_move(&rq->queuelist, &next->queuelist);
rq_set_fifo_time(rq, rq_fifo_time(next));
rq->fifo_time = next->fifo_time;
}

if (cfqq->next_rq == next)
Expand Down Expand Up @@ -2814,7 +2814,7 @@ static struct request *cfq_check_fifo(struct cfq_queue *cfqq)
return NULL;

rq = rq_entry_fifo(cfqq->fifo.next);
if (time_before(jiffies, rq_fifo_time(rq)))
if (time_before(jiffies, rq->fifo_time))
rq = NULL;

cfq_log_cfqq(cfqq->cfqd, cfqq, "fifo=%p", rq);
Expand Down Expand Up @@ -3927,7 +3927,7 @@ static void cfq_insert_request(struct request_queue *q, struct request *rq)
cfq_log_cfqq(cfqd, cfqq, "insert_request");
cfq_init_prio_data(cfqq, RQ_CIC(rq));

rq_set_fifo_time(rq, jiffies + cfqd->cfq_fifo_expire[rq_is_sync(rq)]);
rq->fifo_time = jiffies + cfqd->cfq_fifo_expire[rq_is_sync(rq)];
list_add_tail(&rq->queuelist, &cfqq->fifo);
cfq_add_rq_rb(rq);
cfqg_stats_update_io_add(RQ_CFQG(rq), cfqd->serving_group,
Expand Down
8 changes: 4 additions & 4 deletions block/deadline-iosched.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ deadline_add_request(struct request_queue *q, struct request *rq)
/*
* set expire time and add to fifo list
*/
rq_set_fifo_time(rq, jiffies + dd->fifo_expire[data_dir]);
rq->fifo_time = jiffies + dd->fifo_expire[data_dir];
list_add_tail(&rq->queuelist, &dd->fifo_list[data_dir]);
}

Expand Down Expand Up @@ -174,9 +174,9 @@ deadline_merged_requests(struct request_queue *q, struct request *req,
* and move into next position (next will be deleted) in fifo
*/
if (!list_empty(&req->queuelist) && !list_empty(&next->queuelist)) {
if (time_before(rq_fifo_time(next), rq_fifo_time(req))) {
if (time_before(next->fifo_time, req->fifo_time)) {
list_move(&req->queuelist, &next->queuelist);
rq_set_fifo_time(req, rq_fifo_time(next));
req->fifo_time = next->fifo_time;
}
}

Expand Down Expand Up @@ -230,7 +230,7 @@ static inline int deadline_check_fifo(struct deadline_data *dd, int ddir)
/*
* rq is expired!
*/
if (time_after_eq(jiffies, rq_fifo_time(rq)))
if (time_after_eq(jiffies, rq->fifo_time))
return 1;

return 0;
Expand Down
4 changes: 3 additions & 1 deletion block/partitions/atari.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
* by Guenther Kelleter ([email protected])
*/

#include <linux/compiler.h>

struct partition_info
{
u8 flg; /* bit 0: active; bit 7: bootable */
Expand All @@ -29,6 +31,6 @@ struct rootsector
u32 bsl_st; /* start of bad sector list */
u32 bsl_cnt; /* length of bad sector list */
u16 checksum; /* checksum for bootable disks */
} __attribute__((__packed__));
} __packed;

int atari_partition(struct parsed_partitions *state);
Loading

0 comments on commit 7a48837

Please sign in to comment.