mirror of
https://github.com/armbian/linux-cix.git
synced 2026-01-06 12:30:45 -08:00
Merge tag 'for-6.1/block-2022-10-03' of git://git.kernel.dk/linux
Pull block updates from Jens Axboe:
- NVMe pull requests via Christoph:
- handle number of queue changes in the TCP and RDMA drivers
(Daniel Wagner)
- allow changing the number of queues in nvmet (Daniel Wagner)
- also consider host_iface when checking ip options (Daniel
Wagner)
- don't map pages which can't come from HIGHMEM (Fabio M. De
Francesco)
- avoid unnecessary flush bios in nvmet (Guixin Liu)
- shrink and better pack the nvme_iod structure (Keith Busch)
- add comment for unaligned "fake" nqn (Linjun Bao)
- print actual source IP address through sysfs "address" attr
(Martin Belanger)
- various cleanups (Jackie Liu, Wolfram Sang, Genjian Zhang)
- handle effects after freeing the request (Keith Busch)
- copy firmware_rev on each init (Keith Busch)
- restrict management ioctls to admin (Keith Busch)
- ensure subsystem reset is single threaded (Keith Busch)
- report the actual number of tagset maps in nvme-pci (Keith
Busch)
- small fabrics authentication fixups (Christoph Hellwig)
- add common code for tagset allocation and freeing (Christoph
Hellwig)
- stop using the request_queue in nvmet (Christoph Hellwig)
- set min_align_mask before calculating max_hw_sectors (Rishabh
Bhatnagar)
- send a rediscover uevent when a persistent discovery controller
reconnects (Sagi Grimberg)
- misc nvmet-tcp fixes (Varun Prakash, zhenwei pi)
- MD pull request via Song:
- Various raid5 fix and clean up, by Logan Gunthorpe and David
Sloan.
- Raid10 performance optimization, by Yu Kuai.
- sbitmap wakeup hang fixes (Hugh, Keith, Jan, Yu)
- IO scheduler switching quisce fix (Keith)
- s390/dasd block driver updates (Stefan)
- support for recovery for the ublk driver (ZiyangZhang)
- rnbd drivers fixes and updates (Guoqing, Santosh, ye, Christoph)
- blk-mq and null_blk map fixes (Bart)
- various bcache fixes (Coly, Jilin, Jules)
- nbd signal hang fix (Shigeru)
- block writeback throttling fix (Yu)
- optimize the passthrough mapping handling (me)
- prepare block cgroups to being gendisk based (Christoph)
- get rid of an old PSI hack in the block layer, moving it to the
callers instead where it belongs (Christoph)
- blk-throttle fixes and cleanups (Yu)
- misc fixes and cleanups (Liu Shixin, Liu Song, Miaohe, Pankaj,
Ping-Xiang, Wolfram, Saurabh, Li Jinlin, Li Lei, Lin, Li zeming,
Miaohe, Bart, Coly, Gaosheng
* tag 'for-6.1/block-2022-10-03' of git://git.kernel.dk/linux: (162 commits)
sbitmap: fix lockup while swapping
block: add rationale for not using blk_mq_plug() when applicable
block: adapt blk_mq_plug() to not plug for writes that require a zone lock
s390/dasd: use blk_mq_alloc_disk
blk-cgroup: don't update the blkg lookup hint in blkg_conf_prep
nvmet: don't look at the request_queue in nvmet_bdev_set_limits
nvmet: don't look at the request_queue in nvmet_bdev_zone_mgmt_emulate_all
blk-mq: use quiesced elevator switch when reinitializing queues
block: replace blk_queue_nowait with bdev_nowait
nvme: remove nvme_ctrl_init_connect_q
nvme-loop: use the tagset alloc/free helpers
nvme-loop: store the generic nvme_ctrl in set->driver_data
nvme-loop: initialize sqsize later
nvme-fc: use the tagset alloc/free helpers
nvme-fc: store the generic nvme_ctrl in set->driver_data
nvme-fc: keep ctrl->sqsize in sync with opts->queue_size
nvme-rdma: use the tagset alloc/free helpers
nvme-rdma: store the generic nvme_ctrl in set->driver_data
nvme-tcp: use the tagset alloc/free helpers
nvme-tcp: store the generic nvme_ctrl in set->driver_data
...
This commit is contained in:
@@ -14582,6 +14582,15 @@ F: drivers/nvme/common/
|
||||
F: include/linux/nvme*
|
||||
F: include/uapi/linux/nvme_ioctl.h
|
||||
|
||||
NVM EXPRESS FABRICS AUTHENTICATION
|
||||
M: Hannes Reinecke <hare@suse.de>
|
||||
L: linux-nvme@lists.infradead.org
|
||||
S: Supported
|
||||
F: drivers/nvme/host/auth.c
|
||||
F: drivers/nvme/target/auth.c
|
||||
F: drivers/nvme/target/fabrics-cmd-auth.c
|
||||
F: include/linux/nvme-auth.h
|
||||
|
||||
NVM EXPRESS FC TRANSPORT DRIVERS
|
||||
M: James Smart <james.smart@broadcom.com>
|
||||
L: linux-nvme@lists.infradead.org
|
||||
|
||||
@@ -215,6 +215,11 @@ union scsw {
|
||||
#define SNS2_ENV_DATA_PRESENT 0x10
|
||||
#define SNS2_INPRECISE_END 0x04
|
||||
|
||||
/*
|
||||
* architectured values for PPRC errors
|
||||
*/
|
||||
#define SNS7_INVALID_ON_SEC 0x0e
|
||||
|
||||
/**
|
||||
* scsw_is_tm - check for transport mode scsw
|
||||
* @scsw: pointer to scsw
|
||||
|
||||
@@ -182,6 +182,18 @@ typedef struct format_data_t {
|
||||
unsigned int intensity;
|
||||
} format_data_t;
|
||||
|
||||
/*
|
||||
* struct dasd_copypair_swap_data_t
|
||||
* represents all data necessary to issue a swap of the copy pair relation
|
||||
*/
|
||||
struct dasd_copypair_swap_data_t {
|
||||
char primary[20]; /* BUSID of primary */
|
||||
char secondary[20]; /* BUSID of secondary */
|
||||
|
||||
/* Reserved for future updates. */
|
||||
__u8 reserved[64];
|
||||
};
|
||||
|
||||
/*
|
||||
* values to be used for format_data_t.intensity
|
||||
* 0/8: normal format
|
||||
@@ -326,6 +338,8 @@ struct dasd_snid_ioctl_data {
|
||||
#define BIODASDSATTR _IOW(DASD_IOCTL_LETTER,2,attrib_data_t)
|
||||
/* Release Allocated Space */
|
||||
#define BIODASDRAS _IOW(DASD_IOCTL_LETTER, 3, format_data_t)
|
||||
/* Swap copy pair relation */
|
||||
#define BIODASDCOPYPAIRSWAP _IOW(DASD_IOCTL_LETTER, 4, struct dasd_copypair_swap_data_t)
|
||||
|
||||
/* Get Sense Path Group ID (SNID) data */
|
||||
#define BIODASDSNID _IOWR(DASD_IOCTL_LETTER, 1, struct dasd_snid_ioctl_data)
|
||||
|
||||
@@ -254,17 +254,12 @@ void bfqg_stats_update_completion(struct bfq_group *bfqg, u64 start_time_ns,
|
||||
|
||||
#else /* CONFIG_BFQ_CGROUP_DEBUG */
|
||||
|
||||
void bfqg_stats_update_io_add(struct bfq_group *bfqg, struct bfq_queue *bfqq,
|
||||
blk_opf_t opf) { }
|
||||
void bfqg_stats_update_io_remove(struct bfq_group *bfqg, blk_opf_t opf) { }
|
||||
void bfqg_stats_update_io_merged(struct bfq_group *bfqg, blk_opf_t opf) { }
|
||||
void bfqg_stats_update_completion(struct bfq_group *bfqg, u64 start_time_ns,
|
||||
u64 io_start_time_ns, blk_opf_t opf) { }
|
||||
void bfqg_stats_update_dequeue(struct bfq_group *bfqg) { }
|
||||
void bfqg_stats_set_start_empty_time(struct bfq_group *bfqg) { }
|
||||
void bfqg_stats_update_idle_time(struct bfq_group *bfqg) { }
|
||||
void bfqg_stats_set_start_idle_time(struct bfq_group *bfqg) { }
|
||||
void bfqg_stats_update_avg_queue_size(struct bfq_group *bfqg) { }
|
||||
|
||||
#endif /* CONFIG_BFQ_CGROUP_DEBUG */
|
||||
|
||||
|
||||
@@ -1925,7 +1925,7 @@ static void bfq_bfqq_handle_idle_busy_switch(struct bfq_data *bfqd,
|
||||
bfqq->service_from_backlogged = 0;
|
||||
bfq_clear_bfqq_softrt_update(bfqq);
|
||||
|
||||
bfq_add_bfqq_busy(bfqd, bfqq);
|
||||
bfq_add_bfqq_busy(bfqq);
|
||||
|
||||
/*
|
||||
* Expire in-service queue if preemption may be needed for
|
||||
@@ -2419,7 +2419,7 @@ static void bfq_remove_request(struct request_queue *q,
|
||||
bfqq->next_rq = NULL;
|
||||
|
||||
if (bfq_bfqq_busy(bfqq) && bfqq != bfqd->in_service_queue) {
|
||||
bfq_del_bfqq_busy(bfqd, bfqq, false);
|
||||
bfq_del_bfqq_busy(bfqq, false);
|
||||
/*
|
||||
* bfqq emptied. In normal operation, when
|
||||
* bfqq is empty, bfqq->entity.service and
|
||||
@@ -3098,7 +3098,7 @@ void bfq_release_process_ref(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
||||
*/
|
||||
if (bfq_bfqq_busy(bfqq) && RB_EMPTY_ROOT(&bfqq->sort_list) &&
|
||||
bfqq != bfqd->in_service_queue)
|
||||
bfq_del_bfqq_busy(bfqd, bfqq, false);
|
||||
bfq_del_bfqq_busy(bfqq, false);
|
||||
|
||||
bfq_reassign_last_bfqq(bfqq, NULL);
|
||||
|
||||
@@ -3908,7 +3908,7 @@ static bool __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
*/
|
||||
bfqq->budget_timeout = jiffies;
|
||||
|
||||
bfq_del_bfqq_busy(bfqd, bfqq, true);
|
||||
bfq_del_bfqq_busy(bfqq, true);
|
||||
} else {
|
||||
bfq_requeue_bfqq(bfqd, bfqq, true);
|
||||
/*
|
||||
@@ -5255,9 +5255,7 @@ void bfq_put_queue(struct bfq_queue *bfqq)
|
||||
struct hlist_node *n;
|
||||
struct bfq_group *bfqg = bfqq_group(bfqq);
|
||||
|
||||
if (bfqq->bfqd)
|
||||
bfq_log_bfqq(bfqq->bfqd, bfqq, "put_queue: %p %d",
|
||||
bfqq, bfqq->ref);
|
||||
bfq_log_bfqq(bfqq->bfqd, bfqq, "put_queue: %p %d", bfqq, bfqq->ref);
|
||||
|
||||
bfqq->ref--;
|
||||
if (bfqq->ref)
|
||||
@@ -5321,7 +5319,7 @@ void bfq_put_queue(struct bfq_queue *bfqq)
|
||||
hlist_del_init(&item->woken_list_node);
|
||||
}
|
||||
|
||||
if (bfqq->bfqd && bfqq->bfqd->last_completed_rq_bfqq == bfqq)
|
||||
if (bfqq->bfqd->last_completed_rq_bfqq == bfqq)
|
||||
bfqq->bfqd->last_completed_rq_bfqq = NULL;
|
||||
|
||||
kmem_cache_free(bfq_pool, bfqq);
|
||||
|
||||
@@ -993,20 +993,23 @@ void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg);
|
||||
/* ---------------- cgroups-support interface ---------------- */
|
||||
|
||||
void bfqg_stats_update_legacy_io(struct request_queue *q, struct request *rq);
|
||||
void bfqg_stats_update_io_add(struct bfq_group *bfqg, struct bfq_queue *bfqq,
|
||||
blk_opf_t opf);
|
||||
void bfqg_stats_update_io_remove(struct bfq_group *bfqg, blk_opf_t opf);
|
||||
void bfqg_stats_update_io_merged(struct bfq_group *bfqg, blk_opf_t opf);
|
||||
void bfqg_stats_update_completion(struct bfq_group *bfqg, u64 start_time_ns,
|
||||
u64 io_start_time_ns, blk_opf_t opf);
|
||||
void bfqg_stats_update_dequeue(struct bfq_group *bfqg);
|
||||
void bfqg_stats_set_start_empty_time(struct bfq_group *bfqg);
|
||||
void bfqg_stats_update_idle_time(struct bfq_group *bfqg);
|
||||
void bfqg_stats_set_start_idle_time(struct bfq_group *bfqg);
|
||||
void bfqg_stats_update_avg_queue_size(struct bfq_group *bfqg);
|
||||
void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
struct bfq_group *bfqg);
|
||||
|
||||
#ifdef CONFIG_BFQ_CGROUP_DEBUG
|
||||
void bfqg_stats_update_io_add(struct bfq_group *bfqg, struct bfq_queue *bfqq,
|
||||
blk_opf_t opf);
|
||||
void bfqg_stats_set_start_empty_time(struct bfq_group *bfqg);
|
||||
void bfqg_stats_update_idle_time(struct bfq_group *bfqg);
|
||||
void bfqg_stats_update_avg_queue_size(struct bfq_group *bfqg);
|
||||
#endif
|
||||
|
||||
void bfq_init_entity(struct bfq_entity *entity, struct bfq_group *bfqg);
|
||||
void bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio);
|
||||
void bfq_end_wr_async(struct bfq_data *bfqd);
|
||||
@@ -1077,9 +1080,8 @@ void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq);
|
||||
void bfq_requeue_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
bool expiration);
|
||||
void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
bool expiration);
|
||||
void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq);
|
||||
void bfq_del_bfqq_busy(struct bfq_queue *bfqq, bool expiration);
|
||||
void bfq_add_bfqq_busy(struct bfq_queue *bfqq);
|
||||
|
||||
/* --------------- end of interface of B-WF2Q+ ---------------- */
|
||||
|
||||
|
||||
@@ -1651,9 +1651,10 @@ void bfq_requeue_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
* the service tree. As a special case, it can be invoked during an
|
||||
* expiration.
|
||||
*/
|
||||
void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
bool expiration)
|
||||
void bfq_del_bfqq_busy(struct bfq_queue *bfqq, bool expiration)
|
||||
{
|
||||
struct bfq_data *bfqd = bfqq->bfqd;
|
||||
|
||||
bfq_log_bfqq(bfqd, bfqq, "del from busy");
|
||||
|
||||
bfq_clear_bfqq_busy(bfqq);
|
||||
@@ -1674,8 +1675,10 @@ void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
/*
|
||||
* Called when an inactive queue receives a new request.
|
||||
*/
|
||||
void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
||||
void bfq_add_bfqq_busy(struct bfq_queue *bfqq)
|
||||
{
|
||||
struct bfq_data *bfqd = bfqq->bfqd;
|
||||
|
||||
bfq_log_bfqq(bfqd, bfqq, "add to busy");
|
||||
|
||||
bfq_activate_bfqq(bfqd, bfqq);
|
||||
|
||||
13
block/bio.c
13
block/bio.c
@@ -760,8 +760,6 @@ EXPORT_SYMBOL(bio_put);
|
||||
static int __bio_clone(struct bio *bio, struct bio *bio_src, gfp_t gfp)
|
||||
{
|
||||
bio_set_flag(bio, BIO_CLONED);
|
||||
if (bio_flagged(bio_src, BIO_THROTTLED))
|
||||
bio_set_flag(bio, BIO_THROTTLED);
|
||||
bio->bi_ioprio = bio_src->bi_ioprio;
|
||||
bio->bi_iter = bio_src->bi_iter;
|
||||
|
||||
@@ -1065,9 +1063,6 @@ void __bio_add_page(struct bio *bio, struct page *page,
|
||||
|
||||
bio->bi_iter.bi_size += len;
|
||||
bio->bi_vcnt++;
|
||||
|
||||
if (!bio_flagged(bio, BIO_WORKINGSET) && unlikely(PageWorkingset(page)))
|
||||
bio_set_flag(bio, BIO_WORKINGSET);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__bio_add_page);
|
||||
|
||||
@@ -1276,9 +1271,6 @@ out:
|
||||
* fit into the bio, or are requested in @iter, whatever is smaller. If
|
||||
* MM encounters an error pinning the requested pages, it stops. Error
|
||||
* is returned only if 0 pages could be pinned.
|
||||
*
|
||||
* It's intended for direct IO, so doesn't do PSI tracking, the caller is
|
||||
* responsible for setting BIO_WORKINGSET if necessary.
|
||||
*/
|
||||
int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
|
||||
{
|
||||
@@ -1294,8 +1286,6 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
|
||||
ret = __bio_iov_iter_get_pages(bio, iter);
|
||||
} while (!ret && iov_iter_count(iter) && !bio_full(bio, 0));
|
||||
|
||||
/* don't account direct I/O as memory stall */
|
||||
bio_clear_flag(bio, BIO_WORKINGSET);
|
||||
return bio->bi_vcnt ? 0 : ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bio_iov_iter_get_pages);
|
||||
@@ -1754,7 +1744,8 @@ static int __init init_bio(void)
|
||||
cpuhp_setup_state_multi(CPUHP_BIO_DEAD, "block/bio:dead", NULL,
|
||||
bio_cpu_dead);
|
||||
|
||||
if (bioset_init(&fs_bio_set, BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS))
|
||||
if (bioset_init(&fs_bio_set, BIO_POOL_SIZE, 0,
|
||||
BIOSET_NEED_BVECS | BIOSET_PERCPU_CACHE))
|
||||
panic("bio: can't allocate bios\n");
|
||||
|
||||
if (bioset_integrity_create(&fs_bio_set, BIO_POOL_SIZE))
|
||||
|
||||
@@ -202,19 +202,19 @@ static inline struct blkcg *blkcg_parent(struct blkcg *blkcg)
|
||||
/**
|
||||
* blkg_alloc - allocate a blkg
|
||||
* @blkcg: block cgroup the new blkg is associated with
|
||||
* @q: request_queue the new blkg is associated with
|
||||
* @disk: gendisk the new blkg is associated with
|
||||
* @gfp_mask: allocation mask to use
|
||||
*
|
||||
* Allocate a new blkg assocating @blkcg and @q.
|
||||
*/
|
||||
static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, struct request_queue *q,
|
||||
static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, struct gendisk *disk,
|
||||
gfp_t gfp_mask)
|
||||
{
|
||||
struct blkcg_gq *blkg;
|
||||
int i, cpu;
|
||||
|
||||
/* alloc and init base part */
|
||||
blkg = kzalloc_node(sizeof(*blkg), gfp_mask, q->node);
|
||||
blkg = kzalloc_node(sizeof(*blkg), gfp_mask, disk->queue->node);
|
||||
if (!blkg)
|
||||
return NULL;
|
||||
|
||||
@@ -225,10 +225,10 @@ static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, struct request_queue *q,
|
||||
if (!blkg->iostat_cpu)
|
||||
goto err_free;
|
||||
|
||||
if (!blk_get_queue(q))
|
||||
if (!blk_get_queue(disk->queue))
|
||||
goto err_free;
|
||||
|
||||
blkg->q = q;
|
||||
blkg->q = disk->queue;
|
||||
INIT_LIST_HEAD(&blkg->q_node);
|
||||
spin_lock_init(&blkg->async_bio_lock);
|
||||
bio_list_init(&blkg->async_bios);
|
||||
@@ -243,11 +243,11 @@ static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, struct request_queue *q,
|
||||
struct blkcg_policy *pol = blkcg_policy[i];
|
||||
struct blkg_policy_data *pd;
|
||||
|
||||
if (!blkcg_policy_enabled(q, pol))
|
||||
if (!blkcg_policy_enabled(disk->queue, pol))
|
||||
continue;
|
||||
|
||||
/* alloc per-policy data and attach it to blkg */
|
||||
pd = pol->pd_alloc_fn(gfp_mask, q, blkcg);
|
||||
pd = pol->pd_alloc_fn(gfp_mask, disk->queue, blkcg);
|
||||
if (!pd)
|
||||
goto err_free;
|
||||
|
||||
@@ -263,45 +263,20 @@ err_free:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct blkcg_gq *blkg_lookup_slowpath(struct blkcg *blkcg,
|
||||
struct request_queue *q, bool update_hint)
|
||||
{
|
||||
struct blkcg_gq *blkg;
|
||||
|
||||
/*
|
||||
* Hint didn't match. Look up from the radix tree. Note that the
|
||||
* hint can only be updated under queue_lock as otherwise @blkg
|
||||
* could have already been removed from blkg_tree. The caller is
|
||||
* responsible for grabbing queue_lock if @update_hint.
|
||||
*/
|
||||
blkg = radix_tree_lookup(&blkcg->blkg_tree, q->id);
|
||||
if (blkg && blkg->q == q) {
|
||||
if (update_hint) {
|
||||
lockdep_assert_held(&q->queue_lock);
|
||||
rcu_assign_pointer(blkcg->blkg_hint, blkg);
|
||||
}
|
||||
return blkg;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blkg_lookup_slowpath);
|
||||
|
||||
/*
|
||||
* If @new_blkg is %NULL, this function tries to allocate a new one as
|
||||
* necessary using %GFP_NOWAIT. @new_blkg is always consumed on return.
|
||||
*/
|
||||
static struct blkcg_gq *blkg_create(struct blkcg *blkcg,
|
||||
struct request_queue *q,
|
||||
static struct blkcg_gq *blkg_create(struct blkcg *blkcg, struct gendisk *disk,
|
||||
struct blkcg_gq *new_blkg)
|
||||
{
|
||||
struct blkcg_gq *blkg;
|
||||
int i, ret;
|
||||
|
||||
lockdep_assert_held(&q->queue_lock);
|
||||
lockdep_assert_held(&disk->queue->queue_lock);
|
||||
|
||||
/* request_queue is dying, do not create/recreate a blkg */
|
||||
if (blk_queue_dying(q)) {
|
||||
if (blk_queue_dying(disk->queue)) {
|
||||
ret = -ENODEV;
|
||||
goto err_free_blkg;
|
||||
}
|
||||
@@ -314,7 +289,7 @@ static struct blkcg_gq *blkg_create(struct blkcg *blkcg,
|
||||
|
||||
/* allocate */
|
||||
if (!new_blkg) {
|
||||
new_blkg = blkg_alloc(blkcg, q, GFP_NOWAIT | __GFP_NOWARN);
|
||||
new_blkg = blkg_alloc(blkcg, disk, GFP_NOWAIT | __GFP_NOWARN);
|
||||
if (unlikely(!new_blkg)) {
|
||||
ret = -ENOMEM;
|
||||
goto err_put_css;
|
||||
@@ -324,7 +299,7 @@ static struct blkcg_gq *blkg_create(struct blkcg *blkcg,
|
||||
|
||||
/* link parent */
|
||||
if (blkcg_parent(blkcg)) {
|
||||
blkg->parent = __blkg_lookup(blkcg_parent(blkcg), q, false);
|
||||
blkg->parent = blkg_lookup(blkcg_parent(blkcg), disk->queue);
|
||||
if (WARN_ON_ONCE(!blkg->parent)) {
|
||||
ret = -ENODEV;
|
||||
goto err_put_css;
|
||||
@@ -342,10 +317,10 @@ static struct blkcg_gq *blkg_create(struct blkcg *blkcg,
|
||||
|
||||
/* insert */
|
||||
spin_lock(&blkcg->lock);
|
||||
ret = radix_tree_insert(&blkcg->blkg_tree, q->id, blkg);
|
||||
ret = radix_tree_insert(&blkcg->blkg_tree, disk->queue->id, blkg);
|
||||
if (likely(!ret)) {
|
||||
hlist_add_head_rcu(&blkg->blkcg_node, &blkcg->blkg_list);
|
||||
list_add(&blkg->q_node, &q->blkg_list);
|
||||
list_add(&blkg->q_node, &disk->queue->blkg_list);
|
||||
|
||||
for (i = 0; i < BLKCG_MAX_POLS; i++) {
|
||||
struct blkcg_policy *pol = blkcg_policy[i];
|
||||
@@ -374,19 +349,20 @@ err_free_blkg:
|
||||
/**
|
||||
* blkg_lookup_create - lookup blkg, try to create one if not there
|
||||
* @blkcg: blkcg of interest
|
||||
* @q: request_queue of interest
|
||||
* @disk: gendisk of interest
|
||||
*
|
||||
* Lookup blkg for the @blkcg - @q pair. If it doesn't exist, try to
|
||||
* Lookup blkg for the @blkcg - @disk pair. If it doesn't exist, try to
|
||||
* create one. blkg creation is performed recursively from blkcg_root such
|
||||
* that all non-root blkg's have access to the parent blkg. This function
|
||||
* should be called under RCU read lock and takes @q->queue_lock.
|
||||
* should be called under RCU read lock and takes @disk->queue->queue_lock.
|
||||
*
|
||||
* Returns the blkg or the closest blkg if blkg_create() fails as it walks
|
||||
* down from root.
|
||||
*/
|
||||
static struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg,
|
||||
struct request_queue *q)
|
||||
struct gendisk *disk)
|
||||
{
|
||||
struct request_queue *q = disk->queue;
|
||||
struct blkcg_gq *blkg;
|
||||
unsigned long flags;
|
||||
|
||||
@@ -397,9 +373,13 @@ static struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg,
|
||||
return blkg;
|
||||
|
||||
spin_lock_irqsave(&q->queue_lock, flags);
|
||||
blkg = __blkg_lookup(blkcg, q, true);
|
||||
if (blkg)
|
||||
blkg = blkg_lookup(blkcg, q);
|
||||
if (blkg) {
|
||||
if (blkcg != &blkcg_root &&
|
||||
blkg != rcu_dereference(blkcg->blkg_hint))
|
||||
rcu_assign_pointer(blkcg->blkg_hint, blkg);
|
||||
goto found;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create blkgs walking down from blkcg_root to @blkcg, so that all
|
||||
@@ -412,7 +392,7 @@ static struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg,
|
||||
struct blkcg_gq *ret_blkg = q->root_blkg;
|
||||
|
||||
while (parent) {
|
||||
blkg = __blkg_lookup(parent, q, false);
|
||||
blkg = blkg_lookup(parent, q);
|
||||
if (blkg) {
|
||||
/* remember closest blkg */
|
||||
ret_blkg = blkg;
|
||||
@@ -422,7 +402,7 @@ static struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg,
|
||||
parent = blkcg_parent(parent);
|
||||
}
|
||||
|
||||
blkg = blkg_create(pos, q, NULL);
|
||||
blkg = blkg_create(pos, disk, NULL);
|
||||
if (IS_ERR(blkg)) {
|
||||
blkg = ret_blkg;
|
||||
break;
|
||||
@@ -476,14 +456,9 @@ static void blkg_destroy(struct blkcg_gq *blkg)
|
||||
percpu_ref_kill(&blkg->refcnt);
|
||||
}
|
||||
|
||||
/**
|
||||
* blkg_destroy_all - destroy all blkgs associated with a request_queue
|
||||
* @q: request_queue of interest
|
||||
*
|
||||
* Destroy all blkgs associated with @q.
|
||||
*/
|
||||
static void blkg_destroy_all(struct request_queue *q)
|
||||
static void blkg_destroy_all(struct gendisk *disk)
|
||||
{
|
||||
struct request_queue *q = disk->queue;
|
||||
struct blkcg_gq *blkg, *n;
|
||||
int count = BLKG_DESTROY_BATCH_SIZE;
|
||||
|
||||
@@ -616,19 +591,6 @@ u64 __blkg_prfill_u64(struct seq_file *sf, struct blkg_policy_data *pd, u64 v)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__blkg_prfill_u64);
|
||||
|
||||
/* Performs queue bypass and policy enabled checks then looks up blkg. */
|
||||
static struct blkcg_gq *blkg_lookup_check(struct blkcg *blkcg,
|
||||
const struct blkcg_policy *pol,
|
||||
struct request_queue *q)
|
||||
{
|
||||
WARN_ON_ONCE(!rcu_read_lock_held());
|
||||
lockdep_assert_held(&q->queue_lock);
|
||||
|
||||
if (!blkcg_policy_enabled(q, pol))
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
return __blkg_lookup(blkcg, q, true /* update_hint */);
|
||||
}
|
||||
|
||||
/**
|
||||
* blkcg_conf_open_bdev - parse and open bdev for per-blkg config update
|
||||
* @inputp: input string pointer
|
||||
@@ -684,6 +646,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
|
||||
__acquires(rcu) __acquires(&bdev->bd_queue->queue_lock)
|
||||
{
|
||||
struct block_device *bdev;
|
||||
struct gendisk *disk;
|
||||
struct request_queue *q;
|
||||
struct blkcg_gq *blkg;
|
||||
int ret;
|
||||
@@ -691,8 +654,8 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
|
||||
bdev = blkcg_conf_open_bdev(&input);
|
||||
if (IS_ERR(bdev))
|
||||
return PTR_ERR(bdev);
|
||||
|
||||
q = bdev_get_queue(bdev);
|
||||
disk = bdev->bd_disk;
|
||||
q = disk->queue;
|
||||
|
||||
/*
|
||||
* blkcg_deactivate_policy() requires queue to be frozen, we can grab
|
||||
@@ -705,12 +668,12 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
|
||||
rcu_read_lock();
|
||||
spin_lock_irq(&q->queue_lock);
|
||||
|
||||
blkg = blkg_lookup_check(blkcg, pol, q);
|
||||
if (IS_ERR(blkg)) {
|
||||
ret = PTR_ERR(blkg);
|
||||
if (!blkcg_policy_enabled(q, pol)) {
|
||||
ret = -EOPNOTSUPP;
|
||||
goto fail_unlock;
|
||||
}
|
||||
|
||||
blkg = blkg_lookup(blkcg, q);
|
||||
if (blkg)
|
||||
goto success;
|
||||
|
||||
@@ -724,7 +687,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
|
||||
struct blkcg_gq *new_blkg;
|
||||
|
||||
parent = blkcg_parent(blkcg);
|
||||
while (parent && !__blkg_lookup(parent, q, false)) {
|
||||
while (parent && !blkg_lookup(parent, q)) {
|
||||
pos = parent;
|
||||
parent = blkcg_parent(parent);
|
||||
}
|
||||
@@ -733,7 +696,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
|
||||
spin_unlock_irq(&q->queue_lock);
|
||||
rcu_read_unlock();
|
||||
|
||||
new_blkg = blkg_alloc(pos, q, GFP_KERNEL);
|
||||
new_blkg = blkg_alloc(pos, disk, GFP_KERNEL);
|
||||
if (unlikely(!new_blkg)) {
|
||||
ret = -ENOMEM;
|
||||
goto fail_exit_queue;
|
||||
@@ -748,17 +711,17 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
|
||||
rcu_read_lock();
|
||||
spin_lock_irq(&q->queue_lock);
|
||||
|
||||
blkg = blkg_lookup_check(pos, pol, q);
|
||||
if (IS_ERR(blkg)) {
|
||||
ret = PTR_ERR(blkg);
|
||||
if (!blkcg_policy_enabled(q, pol)) {
|
||||
blkg_free(new_blkg);
|
||||
ret = -EOPNOTSUPP;
|
||||
goto fail_preloaded;
|
||||
}
|
||||
|
||||
blkg = blkg_lookup(pos, q);
|
||||
if (blkg) {
|
||||
blkg_free(new_blkg);
|
||||
} else {
|
||||
blkg = blkg_create(pos, q, new_blkg);
|
||||
blkg = blkg_create(pos, disk, new_blkg);
|
||||
if (IS_ERR(blkg)) {
|
||||
ret = PTR_ERR(blkg);
|
||||
goto fail_preloaded;
|
||||
@@ -915,8 +878,7 @@ static void blkcg_fill_root_iostats(void)
|
||||
class_dev_iter_init(&iter, &block_class, NULL, &disk_type);
|
||||
while ((dev = class_dev_iter_next(&iter))) {
|
||||
struct block_device *bdev = dev_to_bdev(dev);
|
||||
struct blkcg_gq *blkg =
|
||||
blk_queue_root_blkg(bdev_get_queue(bdev));
|
||||
struct blkcg_gq *blkg = bdev->bd_disk->queue->root_blkg;
|
||||
struct blkg_iostat tmp;
|
||||
int cpu;
|
||||
unsigned long flags;
|
||||
@@ -1255,25 +1217,16 @@ static int blkcg_css_online(struct cgroup_subsys_state *css)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* blkcg_init_queue - initialize blkcg part of request queue
|
||||
* @q: request_queue to initialize
|
||||
*
|
||||
* Called from blk_alloc_queue(). Responsible for initializing blkcg
|
||||
* part of new request_queue @q.
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -errno on failure.
|
||||
*/
|
||||
int blkcg_init_queue(struct request_queue *q)
|
||||
int blkcg_init_disk(struct gendisk *disk)
|
||||
{
|
||||
struct request_queue *q = disk->queue;
|
||||
struct blkcg_gq *new_blkg, *blkg;
|
||||
bool preloaded;
|
||||
int ret;
|
||||
|
||||
INIT_LIST_HEAD(&q->blkg_list);
|
||||
|
||||
new_blkg = blkg_alloc(&blkcg_root, q, GFP_KERNEL);
|
||||
new_blkg = blkg_alloc(&blkcg_root, disk, GFP_KERNEL);
|
||||
if (!new_blkg)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -1282,7 +1235,7 @@ int blkcg_init_queue(struct request_queue *q)
|
||||
/* Make sure the root blkg exists. */
|
||||
/* spin_lock_irq can serve as RCU read-side critical section. */
|
||||
spin_lock_irq(&q->queue_lock);
|
||||
blkg = blkg_create(&blkcg_root, q, new_blkg);
|
||||
blkg = blkg_create(&blkcg_root, disk, new_blkg);
|
||||
if (IS_ERR(blkg))
|
||||
goto err_unlock;
|
||||
q->root_blkg = blkg;
|
||||
@@ -1291,25 +1244,26 @@ int blkcg_init_queue(struct request_queue *q)
|
||||
if (preloaded)
|
||||
radix_tree_preload_end();
|
||||
|
||||
ret = blk_ioprio_init(q);
|
||||
ret = blk_ioprio_init(disk);
|
||||
if (ret)
|
||||
goto err_destroy_all;
|
||||
|
||||
ret = blk_throtl_init(q);
|
||||
ret = blk_throtl_init(disk);
|
||||
if (ret)
|
||||
goto err_destroy_all;
|
||||
goto err_ioprio_exit;
|
||||
|
||||
ret = blk_iolatency_init(q);
|
||||
if (ret) {
|
||||
blk_throtl_exit(q);
|
||||
blk_ioprio_exit(q);
|
||||
goto err_destroy_all;
|
||||
}
|
||||
ret = blk_iolatency_init(disk);
|
||||
if (ret)
|
||||
goto err_throtl_exit;
|
||||
|
||||
return 0;
|
||||
|
||||
err_throtl_exit:
|
||||
blk_throtl_exit(disk);
|
||||
err_ioprio_exit:
|
||||
blk_ioprio_exit(disk);
|
||||
err_destroy_all:
|
||||
blkg_destroy_all(q);
|
||||
blkg_destroy_all(disk);
|
||||
return ret;
|
||||
err_unlock:
|
||||
spin_unlock_irq(&q->queue_lock);
|
||||
@@ -1318,16 +1272,10 @@ err_unlock:
|
||||
return PTR_ERR(blkg);
|
||||
}
|
||||
|
||||
/**
|
||||
* blkcg_exit_queue - exit and release blkcg part of request_queue
|
||||
* @q: request_queue being released
|
||||
*
|
||||
* Called from blk_exit_queue(). Responsible for exiting blkcg part.
|
||||
*/
|
||||
void blkcg_exit_queue(struct request_queue *q)
|
||||
void blkcg_exit_disk(struct gendisk *disk)
|
||||
{
|
||||
blkg_destroy_all(q);
|
||||
blk_throtl_exit(q);
|
||||
blkg_destroy_all(disk);
|
||||
blk_throtl_exit(disk);
|
||||
}
|
||||
|
||||
static void blkcg_bind(struct cgroup_subsys_state *root_css)
|
||||
@@ -1836,13 +1784,13 @@ out:
|
||||
|
||||
/**
|
||||
* blkcg_schedule_throttle - this task needs to check for throttling
|
||||
* @q: the request queue IO was submitted on
|
||||
* @gendisk: disk to throttle
|
||||
* @use_memdelay: do we charge this to memory delay for PSI
|
||||
*
|
||||
* This is called by the IO controller when we know there's delay accumulated
|
||||
* for the blkg for this task. We do not pass the blkg because there are places
|
||||
* we call this that may not have that information, the swapping code for
|
||||
* instance will only have a request_queue at that point. This set's the
|
||||
* instance will only have a block_device at that point. This set's the
|
||||
* notify_resume for the task to check and see if it requires throttling before
|
||||
* returning to user space.
|
||||
*
|
||||
@@ -1851,8 +1799,10 @@ out:
|
||||
* throttle once. If the task needs to be throttled again it'll need to be
|
||||
* re-set at the next time we see the task.
|
||||
*/
|
||||
void blkcg_schedule_throttle(struct request_queue *q, bool use_memdelay)
|
||||
void blkcg_schedule_throttle(struct gendisk *disk, bool use_memdelay)
|
||||
{
|
||||
struct request_queue *q = disk->queue;
|
||||
|
||||
if (unlikely(current->flags & PF_KTHREAD))
|
||||
return;
|
||||
|
||||
@@ -1902,8 +1852,7 @@ static inline struct blkcg_gq *blkg_tryget_closest(struct bio *bio,
|
||||
struct blkcg_gq *blkg, *ret_blkg = NULL;
|
||||
|
||||
rcu_read_lock();
|
||||
blkg = blkg_lookup_create(css_to_blkcg(css),
|
||||
bdev_get_queue(bio->bi_bdev));
|
||||
blkg = blkg_lookup_create(css_to_blkcg(css), bio->bi_bdev->bd_disk);
|
||||
while (blkg) {
|
||||
if (blkg_tryget(blkg)) {
|
||||
ret_blkg = blkg;
|
||||
|
||||
@@ -178,10 +178,8 @@ struct blkcg_policy {
|
||||
extern struct blkcg blkcg_root;
|
||||
extern bool blkcg_debug_stats;
|
||||
|
||||
struct blkcg_gq *blkg_lookup_slowpath(struct blkcg *blkcg,
|
||||
struct request_queue *q, bool update_hint);
|
||||
int blkcg_init_queue(struct request_queue *q);
|
||||
void blkcg_exit_queue(struct request_queue *q);
|
||||
int blkcg_init_disk(struct gendisk *disk);
|
||||
void blkcg_exit_disk(struct gendisk *disk);
|
||||
|
||||
/* Blkio controller policy registration */
|
||||
int blkcg_policy_register(struct blkcg_policy *pol);
|
||||
@@ -227,22 +225,21 @@ static inline bool bio_issue_as_root_blkg(struct bio *bio)
|
||||
}
|
||||
|
||||
/**
|
||||
* __blkg_lookup - internal version of blkg_lookup()
|
||||
* blkg_lookup - lookup blkg for the specified blkcg - q pair
|
||||
* @blkcg: blkcg of interest
|
||||
* @q: request_queue of interest
|
||||
* @update_hint: whether to update lookup hint with the result or not
|
||||
*
|
||||
* This is internal version and shouldn't be used by policy
|
||||
* implementations. Looks up blkgs for the @blkcg - @q pair regardless of
|
||||
* @q's bypass state. If @update_hint is %true, the caller should be
|
||||
* holding @q->queue_lock and lookup hint is updated on success.
|
||||
* Lookup blkg for the @blkcg - @q pair.
|
||||
|
||||
* Must be called in a RCU critical section.
|
||||
*/
|
||||
static inline struct blkcg_gq *__blkg_lookup(struct blkcg *blkcg,
|
||||
struct request_queue *q,
|
||||
bool update_hint)
|
||||
static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg,
|
||||
struct request_queue *q)
|
||||
{
|
||||
struct blkcg_gq *blkg;
|
||||
|
||||
WARN_ON_ONCE(!rcu_read_lock_held());
|
||||
|
||||
if (blkcg == &blkcg_root)
|
||||
return q->root_blkg;
|
||||
|
||||
@@ -250,33 +247,10 @@ static inline struct blkcg_gq *__blkg_lookup(struct blkcg *blkcg,
|
||||
if (blkg && blkg->q == q)
|
||||
return blkg;
|
||||
|
||||
return blkg_lookup_slowpath(blkcg, q, update_hint);
|
||||
}
|
||||
|
||||
/**
|
||||
* blkg_lookup - lookup blkg for the specified blkcg - q pair
|
||||
* @blkcg: blkcg of interest
|
||||
* @q: request_queue of interest
|
||||
*
|
||||
* Lookup blkg for the @blkcg - @q pair. This function should be called
|
||||
* under RCU read lock.
|
||||
*/
|
||||
static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg,
|
||||
struct request_queue *q)
|
||||
{
|
||||
WARN_ON_ONCE(!rcu_read_lock_held());
|
||||
return __blkg_lookup(blkcg, q, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* blk_queue_root_blkg - return blkg for the (blkcg_root, @q) pair
|
||||
* @q: request_queue of interest
|
||||
*
|
||||
* Lookup blkg for @q at the root level. See also blkg_lookup().
|
||||
*/
|
||||
static inline struct blkcg_gq *blk_queue_root_blkg(struct request_queue *q)
|
||||
{
|
||||
return q->root_blkg;
|
||||
blkg = radix_tree_lookup(&blkcg->blkg_tree, q->id);
|
||||
if (blkg && blkg->q != q)
|
||||
blkg = NULL;
|
||||
return blkg;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -373,8 +347,8 @@ static inline void blkg_put(struct blkcg_gq *blkg)
|
||||
*/
|
||||
#define blkg_for_each_descendant_pre(d_blkg, pos_css, p_blkg) \
|
||||
css_for_each_descendant_pre((pos_css), &(p_blkg)->blkcg->css) \
|
||||
if (((d_blkg) = __blkg_lookup(css_to_blkcg(pos_css), \
|
||||
(p_blkg)->q, false)))
|
||||
if (((d_blkg) = blkg_lookup(css_to_blkcg(pos_css), \
|
||||
(p_blkg)->q)))
|
||||
|
||||
/**
|
||||
* blkg_for_each_descendant_post - post-order walk of a blkg's descendants
|
||||
@@ -388,8 +362,8 @@ static inline void blkg_put(struct blkcg_gq *blkg)
|
||||
*/
|
||||
#define blkg_for_each_descendant_post(d_blkg, pos_css, p_blkg) \
|
||||
css_for_each_descendant_post((pos_css), &(p_blkg)->blkcg->css) \
|
||||
if (((d_blkg) = __blkg_lookup(css_to_blkcg(pos_css), \
|
||||
(p_blkg)->q, false)))
|
||||
if (((d_blkg) = blkg_lookup(css_to_blkcg(pos_css), \
|
||||
(p_blkg)->q)))
|
||||
|
||||
bool __blkcg_punt_bio_submit(struct bio *bio);
|
||||
|
||||
@@ -507,10 +481,8 @@ struct blkcg {
|
||||
};
|
||||
|
||||
static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, void *key) { return NULL; }
|
||||
static inline struct blkcg_gq *blk_queue_root_blkg(struct request_queue *q)
|
||||
{ return NULL; }
|
||||
static inline int blkcg_init_queue(struct request_queue *q) { return 0; }
|
||||
static inline void blkcg_exit_queue(struct request_queue *q) { }
|
||||
static inline int blkcg_init_disk(struct gendisk *disk) { return 0; }
|
||||
static inline void blkcg_exit_disk(struct gendisk *disk) { }
|
||||
static inline int blkcg_policy_register(struct blkcg_policy *pol) { return 0; }
|
||||
static inline void blkcg_policy_unregister(struct blkcg_policy *pol) { }
|
||||
static inline int blkcg_activate_policy(struct request_queue *q,
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#include <linux/t10-pi.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/bpf.h>
|
||||
#include <linux/psi.h>
|
||||
#include <linux/part_stat.h>
|
||||
#include <linux/sched/sysctl.h>
|
||||
#include <linux/blk-crypto.h>
|
||||
@@ -487,18 +486,15 @@ static int __init fail_make_request_debugfs(void)
|
||||
late_initcall(fail_make_request_debugfs);
|
||||
#endif /* CONFIG_FAIL_MAKE_REQUEST */
|
||||
|
||||
static inline bool bio_check_ro(struct bio *bio)
|
||||
static inline void bio_check_ro(struct bio *bio)
|
||||
{
|
||||
if (op_is_write(bio_op(bio)) && bdev_read_only(bio->bi_bdev)) {
|
||||
if (op_is_flush(bio->bi_opf) && !bio_sectors(bio))
|
||||
return false;
|
||||
return;
|
||||
pr_warn("Trying to write to read-only block-device %pg\n",
|
||||
bio->bi_bdev);
|
||||
/* Older lvm-tools actually trigger this */
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static noinline int should_fail_bio(struct bio *bio)
|
||||
@@ -717,13 +713,12 @@ void submit_bio_noacct(struct bio *bio)
|
||||
* For a REQ_NOWAIT based request, return -EOPNOTSUPP
|
||||
* if queue does not support NOWAIT.
|
||||
*/
|
||||
if ((bio->bi_opf & REQ_NOWAIT) && !blk_queue_nowait(q))
|
||||
if ((bio->bi_opf & REQ_NOWAIT) && !bdev_nowait(bdev))
|
||||
goto not_supported;
|
||||
|
||||
if (should_fail_bio(bio))
|
||||
goto end_io;
|
||||
if (unlikely(bio_check_ro(bio)))
|
||||
goto end_io;
|
||||
bio_check_ro(bio);
|
||||
if (!bio_flagged(bio, BIO_REMAPPED)) {
|
||||
if (unlikely(bio_check_eod(bio)))
|
||||
goto end_io;
|
||||
@@ -814,7 +809,7 @@ EXPORT_SYMBOL(submit_bio_noacct);
|
||||
*
|
||||
* The success/failure status of the request, along with notification of
|
||||
* completion, is delivered asynchronously through the ->bi_end_io() callback
|
||||
* in @bio. The bio must NOT be touched by thecaller until ->bi_end_io() has
|
||||
* in @bio. The bio must NOT be touched by the caller until ->bi_end_io() has
|
||||
* been called.
|
||||
*/
|
||||
void submit_bio(struct bio *bio)
|
||||
@@ -829,22 +824,6 @@ void submit_bio(struct bio *bio)
|
||||
count_vm_events(PGPGOUT, bio_sectors(bio));
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're reading data that is part of the userspace workingset, count
|
||||
* submission time as memory stall. When the device is congested, or
|
||||
* the submitting cgroup IO-throttled, submission can be a significant
|
||||
* part of overall IO time.
|
||||
*/
|
||||
if (unlikely(bio_op(bio) == REQ_OP_READ &&
|
||||
bio_flagged(bio, BIO_WORKINGSET))) {
|
||||
unsigned long pflags;
|
||||
|
||||
psi_memstall_enter(&pflags);
|
||||
submit_bio_noacct(bio);
|
||||
psi_memstall_leave(&pflags);
|
||||
return;
|
||||
}
|
||||
|
||||
submit_bio_noacct(bio);
|
||||
}
|
||||
EXPORT_SYMBOL(submit_bio);
|
||||
@@ -871,6 +850,12 @@ int bio_poll(struct bio *bio, struct io_comp_batch *iob, unsigned int flags)
|
||||
!test_bit(QUEUE_FLAG_POLL, &q->queue_flags))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* As the requests that require a zone lock are not plugged in the
|
||||
* first place, directly accessing the plug instead of using
|
||||
* blk_mq_plug() should not have any consequences during flushing for
|
||||
* zoned devices.
|
||||
*/
|
||||
blk_flush_plug(current->plug, false);
|
||||
|
||||
if (bio_queue_enter(bio))
|
||||
|
||||
@@ -664,17 +664,13 @@ static struct ioc *q_to_ioc(struct request_queue *q)
|
||||
return rqos_to_ioc(rq_qos_id(q, RQ_QOS_COST));
|
||||
}
|
||||
|
||||
static const char *q_name(struct request_queue *q)
|
||||
{
|
||||
if (blk_queue_registered(q))
|
||||
return kobject_name(q->kobj.parent);
|
||||
else
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
static const char __maybe_unused *ioc_name(struct ioc *ioc)
|
||||
{
|
||||
return q_name(ioc->rqos.q);
|
||||
struct gendisk *disk = ioc->rqos.q->disk;
|
||||
|
||||
if (!disk)
|
||||
return "<unknown>";
|
||||
return disk->disk_name;
|
||||
}
|
||||
|
||||
static struct ioc_gq *pd_to_iocg(struct blkg_policy_data *pd)
|
||||
@@ -1430,7 +1426,7 @@ static int iocg_wake_fn(struct wait_queue_entry *wq_entry, unsigned mode,
|
||||
int flags, void *key)
|
||||
{
|
||||
struct iocg_wait *wait = container_of(wq_entry, struct iocg_wait, wait);
|
||||
struct iocg_wake_ctx *ctx = (struct iocg_wake_ctx *)key;
|
||||
struct iocg_wake_ctx *ctx = key;
|
||||
u64 cost = abs_cost_to_cost(wait->abs_cost, ctx->hw_inuse);
|
||||
|
||||
ctx->vbudget -= cost;
|
||||
@@ -2640,7 +2636,7 @@ retry_lock:
|
||||
if (use_debt) {
|
||||
iocg_incur_debt(iocg, abs_cost, &now);
|
||||
if (iocg_kick_delay(iocg, &now))
|
||||
blkcg_schedule_throttle(rqos->q,
|
||||
blkcg_schedule_throttle(rqos->q->disk,
|
||||
(bio->bi_opf & REQ_SWAP) == REQ_SWAP);
|
||||
iocg_unlock(iocg, ioc_locked, &flags);
|
||||
return;
|
||||
@@ -2741,7 +2737,7 @@ static void ioc_rqos_merge(struct rq_qos *rqos, struct request *rq,
|
||||
if (likely(!list_empty(&iocg->active_list))) {
|
||||
iocg_incur_debt(iocg, abs_cost, &now);
|
||||
if (iocg_kick_delay(iocg, &now))
|
||||
blkcg_schedule_throttle(rqos->q,
|
||||
blkcg_schedule_throttle(rqos->q->disk,
|
||||
(bio->bi_opf & REQ_SWAP) == REQ_SWAP);
|
||||
} else {
|
||||
iocg_commit_bio(iocg, bio, abs_cost, cost);
|
||||
@@ -2832,8 +2828,9 @@ static struct rq_qos_ops ioc_rqos_ops = {
|
||||
.exit = ioc_rqos_exit,
|
||||
};
|
||||
|
||||
static int blk_iocost_init(struct request_queue *q)
|
||||
static int blk_iocost_init(struct gendisk *disk)
|
||||
{
|
||||
struct request_queue *q = disk->queue;
|
||||
struct ioc *ioc;
|
||||
struct rq_qos *rqos;
|
||||
int i, cpu, ret;
|
||||
@@ -3170,6 +3167,7 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
|
||||
size_t nbytes, loff_t off)
|
||||
{
|
||||
struct block_device *bdev;
|
||||
struct gendisk *disk;
|
||||
struct ioc *ioc;
|
||||
u32 qos[NR_QOS_PARAMS];
|
||||
bool enable, user;
|
||||
@@ -3180,12 +3178,13 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
|
||||
if (IS_ERR(bdev))
|
||||
return PTR_ERR(bdev);
|
||||
|
||||
ioc = q_to_ioc(bdev_get_queue(bdev));
|
||||
disk = bdev->bd_disk;
|
||||
ioc = q_to_ioc(disk->queue);
|
||||
if (!ioc) {
|
||||
ret = blk_iocost_init(bdev_get_queue(bdev));
|
||||
ret = blk_iocost_init(disk);
|
||||
if (ret)
|
||||
goto err;
|
||||
ioc = q_to_ioc(bdev_get_queue(bdev));
|
||||
ioc = q_to_ioc(disk->queue);
|
||||
}
|
||||
|
||||
spin_lock_irq(&ioc->lock);
|
||||
@@ -3262,11 +3261,11 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
|
||||
spin_lock_irq(&ioc->lock);
|
||||
|
||||
if (enable) {
|
||||
blk_stat_enable_accounting(ioc->rqos.q);
|
||||
blk_queue_flag_set(QUEUE_FLAG_RQ_ALLOC_TIME, ioc->rqos.q);
|
||||
blk_stat_enable_accounting(disk->queue);
|
||||
blk_queue_flag_set(QUEUE_FLAG_RQ_ALLOC_TIME, disk->queue);
|
||||
ioc->enabled = true;
|
||||
} else {
|
||||
blk_queue_flag_clear(QUEUE_FLAG_RQ_ALLOC_TIME, ioc->rqos.q);
|
||||
blk_queue_flag_clear(QUEUE_FLAG_RQ_ALLOC_TIME, disk->queue);
|
||||
ioc->enabled = false;
|
||||
}
|
||||
|
||||
@@ -3349,7 +3348,7 @@ static ssize_t ioc_cost_model_write(struct kernfs_open_file *of, char *input,
|
||||
|
||||
ioc = q_to_ioc(bdev_get_queue(bdev));
|
||||
if (!ioc) {
|
||||
ret = blk_iocost_init(bdev_get_queue(bdev));
|
||||
ret = blk_iocost_init(bdev->bd_disk);
|
||||
if (ret)
|
||||
goto err;
|
||||
ioc = q_to_ioc(bdev_get_queue(bdev));
|
||||
|
||||
@@ -292,7 +292,7 @@ static void __blkcg_iolatency_throttle(struct rq_qos *rqos,
|
||||
unsigned use_delay = atomic_read(&lat_to_blkg(iolat)->use_delay);
|
||||
|
||||
if (use_delay)
|
||||
blkcg_schedule_throttle(rqos->q, use_memdelay);
|
||||
blkcg_schedule_throttle(rqos->q->disk, use_memdelay);
|
||||
|
||||
/*
|
||||
* To avoid priority inversions we want to just take a slot if we are
|
||||
@@ -756,8 +756,9 @@ static void blkiolatency_enable_work_fn(struct work_struct *work)
|
||||
}
|
||||
}
|
||||
|
||||
int blk_iolatency_init(struct request_queue *q)
|
||||
int blk_iolatency_init(struct gendisk *disk)
|
||||
{
|
||||
struct request_queue *q = disk->queue;
|
||||
struct blk_iolatency *blkiolat;
|
||||
struct rq_qos *rqos;
|
||||
int ret;
|
||||
|
||||
@@ -202,14 +202,14 @@ void blkcg_set_ioprio(struct bio *bio)
|
||||
bio->bi_ioprio = prio;
|
||||
}
|
||||
|
||||
void blk_ioprio_exit(struct request_queue *q)
|
||||
void blk_ioprio_exit(struct gendisk *disk)
|
||||
{
|
||||
blkcg_deactivate_policy(q, &ioprio_policy);
|
||||
blkcg_deactivate_policy(disk->queue, &ioprio_policy);
|
||||
}
|
||||
|
||||
int blk_ioprio_init(struct request_queue *q)
|
||||
int blk_ioprio_init(struct gendisk *disk)
|
||||
{
|
||||
return blkcg_activate_policy(q, &ioprio_policy);
|
||||
return blkcg_activate_policy(disk->queue, &ioprio_policy);
|
||||
}
|
||||
|
||||
static int __init ioprio_init(void)
|
||||
|
||||
@@ -9,15 +9,15 @@ struct request_queue;
|
||||
struct bio;
|
||||
|
||||
#ifdef CONFIG_BLK_CGROUP_IOPRIO
|
||||
int blk_ioprio_init(struct request_queue *q);
|
||||
void blk_ioprio_exit(struct request_queue *q);
|
||||
int blk_ioprio_init(struct gendisk *disk);
|
||||
void blk_ioprio_exit(struct gendisk *disk);
|
||||
void blkcg_set_ioprio(struct bio *bio);
|
||||
#else
|
||||
static inline int blk_ioprio_init(struct request_queue *q)
|
||||
static inline int blk_ioprio_init(struct gendisk *disk)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void blk_ioprio_exit(struct request_queue *q)
|
||||
static inline void blk_ioprio_exit(struct gendisk *disk)
|
||||
{
|
||||
}
|
||||
static inline void blkcg_set_ioprio(struct bio *bio)
|
||||
|
||||
@@ -158,7 +158,7 @@ static int bio_copy_user_iov(struct request *rq, struct rq_map_data *map_data,
|
||||
bio_init(bio, NULL, bio->bi_inline_vecs, nr_pages, req_op(rq));
|
||||
|
||||
if (map_data) {
|
||||
nr_pages = 1 << map_data->page_order;
|
||||
nr_pages = 1U << map_data->page_order;
|
||||
i = map_data->offset / PAGE_SIZE;
|
||||
}
|
||||
while (len) {
|
||||
@@ -231,6 +231,16 @@ out_bmd:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void bio_map_put(struct bio *bio)
|
||||
{
|
||||
if (bio->bi_opf & REQ_ALLOC_CACHE) {
|
||||
bio_put(bio);
|
||||
} else {
|
||||
bio_uninit(bio);
|
||||
kfree(bio);
|
||||
}
|
||||
}
|
||||
|
||||
static int bio_map_user_iov(struct request *rq, struct iov_iter *iter,
|
||||
gfp_t gfp_mask)
|
||||
{
|
||||
@@ -243,18 +253,34 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter,
|
||||
if (!iov_iter_count(iter))
|
||||
return -EINVAL;
|
||||
|
||||
bio = bio_kmalloc(nr_vecs, gfp_mask);
|
||||
if (!bio)
|
||||
return -ENOMEM;
|
||||
bio_init(bio, NULL, bio->bi_inline_vecs, nr_vecs, req_op(rq));
|
||||
if (rq->cmd_flags & REQ_POLLED) {
|
||||
blk_opf_t opf = rq->cmd_flags | REQ_ALLOC_CACHE;
|
||||
|
||||
bio = bio_alloc_bioset(NULL, nr_vecs, opf, gfp_mask,
|
||||
&fs_bio_set);
|
||||
if (!bio)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
bio = bio_kmalloc(nr_vecs, gfp_mask);
|
||||
if (!bio)
|
||||
return -ENOMEM;
|
||||
bio_init(bio, NULL, bio->bi_inline_vecs, nr_vecs, req_op(rq));
|
||||
}
|
||||
|
||||
while (iov_iter_count(iter)) {
|
||||
struct page **pages;
|
||||
struct page **pages, *stack_pages[UIO_FASTIOV];
|
||||
ssize_t bytes;
|
||||
size_t offs, added = 0;
|
||||
size_t offs;
|
||||
int npages;
|
||||
|
||||
bytes = iov_iter_get_pages_alloc2(iter, &pages, LONG_MAX, &offs);
|
||||
if (nr_vecs <= ARRAY_SIZE(stack_pages)) {
|
||||
pages = stack_pages;
|
||||
bytes = iov_iter_get_pages2(iter, pages, LONG_MAX,
|
||||
nr_vecs, &offs);
|
||||
} else {
|
||||
bytes = iov_iter_get_pages_alloc2(iter, &pages,
|
||||
LONG_MAX, &offs);
|
||||
}
|
||||
if (unlikely(bytes <= 0)) {
|
||||
ret = bytes ? bytes : -EFAULT;
|
||||
goto out_unmap;
|
||||
@@ -280,7 +306,6 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter,
|
||||
break;
|
||||
}
|
||||
|
||||
added += n;
|
||||
bytes -= n;
|
||||
offs = 0;
|
||||
}
|
||||
@@ -290,7 +315,8 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter,
|
||||
*/
|
||||
while (j < npages)
|
||||
put_page(pages[j++]);
|
||||
kvfree(pages);
|
||||
if (pages != stack_pages)
|
||||
kvfree(pages);
|
||||
/* couldn't stuff something into bio? */
|
||||
if (bytes) {
|
||||
iov_iter_revert(iter, bytes);
|
||||
@@ -305,8 +331,7 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter,
|
||||
|
||||
out_unmap:
|
||||
bio_release_pages(bio, false);
|
||||
bio_uninit(bio);
|
||||
kfree(bio);
|
||||
bio_map_put(bio);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -611,8 +636,7 @@ int blk_rq_unmap_user(struct bio *bio)
|
||||
|
||||
next_bio = bio;
|
||||
bio = bio->bi_next;
|
||||
bio_uninit(next_bio);
|
||||
kfree(next_bio);
|
||||
bio_map_put(next_bio);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -32,7 +32,7 @@ static int get_first_sibling(unsigned int cpu)
|
||||
return cpu;
|
||||
}
|
||||
|
||||
int blk_mq_map_queues(struct blk_mq_queue_map *qmap)
|
||||
void blk_mq_map_queues(struct blk_mq_queue_map *qmap)
|
||||
{
|
||||
unsigned int *map = qmap->mq_map;
|
||||
unsigned int nr_queues = qmap->nr_queues;
|
||||
@@ -70,8 +70,6 @@ int blk_mq_map_queues(struct blk_mq_queue_map *qmap)
|
||||
map[cpu] = map[first_sibling];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blk_mq_map_queues);
|
||||
|
||||
|
||||
@@ -807,8 +807,6 @@ static const char *rq_qos_id_to_name(enum rq_qos_id id)
|
||||
return "latency";
|
||||
case RQ_QOS_COST:
|
||||
return "cost";
|
||||
case RQ_QOS_IOPRIO:
|
||||
return "ioprio";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
* that maps a queue to the CPUs that have irq affinity for the corresponding
|
||||
* vector.
|
||||
*/
|
||||
int blk_mq_pci_map_queues(struct blk_mq_queue_map *qmap, struct pci_dev *pdev,
|
||||
int offset)
|
||||
void blk_mq_pci_map_queues(struct blk_mq_queue_map *qmap, struct pci_dev *pdev,
|
||||
int offset)
|
||||
{
|
||||
const struct cpumask *mask;
|
||||
unsigned int queue, cpu;
|
||||
@@ -38,11 +38,10 @@ int blk_mq_pci_map_queues(struct blk_mq_queue_map *qmap, struct pci_dev *pdev,
|
||||
qmap->mq_map[cpu] = qmap->queue_offset + queue;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return;
|
||||
|
||||
fallback:
|
||||
WARN_ON_ONCE(qmap->nr_queues > 1);
|
||||
blk_mq_clear_mq_map(qmap);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blk_mq_pci_map_queues);
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* @set->nr_hw_queues, or @dev does not provide an affinity mask for a
|
||||
* vector, we fallback to the naive mapping.
|
||||
*/
|
||||
int blk_mq_rdma_map_queues(struct blk_mq_queue_map *map,
|
||||
void blk_mq_rdma_map_queues(struct blk_mq_queue_map *map,
|
||||
struct ib_device *dev, int first_vec)
|
||||
{
|
||||
const struct cpumask *mask;
|
||||
@@ -36,9 +36,9 @@ int blk_mq_rdma_map_queues(struct blk_mq_queue_map *map,
|
||||
map->mq_map[cpu] = map->queue_offset + queue;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return;
|
||||
|
||||
fallback:
|
||||
return blk_mq_map_queues(map);
|
||||
blk_mq_map_queues(map);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blk_mq_rdma_map_queues);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user