Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.dk/linux-block
Browse files Browse the repository at this point in the history
Pull block fixes from Jens Axboe:
 "A small collection of fixes that should go into this series. This
  contains:

   - NVMe pull request from Christoph, with various fixes for nvme
     proper and nvme-fc.

   - disable runtime PM for blk-mq for now.

     With scsi now defaulting to using blk-mq, this reared its head as
     an issue. Longer term we'll fix up runtime PM for blk-mq, for now
     just disable it to prevent a hang on laptop resume for some folks.

   - blk-mq CPU <-> hw queue map fix from Christoph.

   - xen/blkfront pull request from Konrad, with two small fixes for the
     blkfront driver.

   - a few fixups for nbd from Joseph.

   - a stable fix for pblk from Javier"

* 'for-linus' of git://git.kernel.dk/linux-block:
  lightnvm: pblk: advance bio according to lba index
  nvme: validate admin queue before unquiesce
  nbd: clear disconnected on reconnect
  nvme-pci: fix HMB size calculation
  nvme-fc: revise TRADDR parsing
  nvme-fc: address target disconnect race conditions in fcp io submit
  nvme: fabrics commands should use the fctype field for data direction
  nvme: also provide a UUID in the WWID sysfs attribute
  xen/blkfront: always allocate grants first from per-queue persistent grants
  xen-blkfront: fix mq start/stop race
  blk-mq: map queues to all present CPUs
  block: disable runtime-pm for blk-mq
  xen-blkfront: Fix handling of non-supported operations
  nbd: only set sndtimeo if we have a timeout set
  nbd: take tx_lock before disconnecting
  nbd: allow multiple disconnects to be sent
  • Loading branch information
Linus Torvalds committed Jul 28, 2017
2 parents a2d4875 + 75cb8e9 commit 0fa8dc4
Show file tree
Hide file tree
Showing 13 changed files with 197 additions and 138 deletions.
4 changes: 4 additions & 0 deletions block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -3421,6 +3421,10 @@ EXPORT_SYMBOL(blk_finish_plug);
*/
void blk_pm_runtime_init(struct request_queue *q, struct device *dev)
{
/* not support for RQF_PM and ->rpm_status in blk-mq yet */
if (q->mq_ops)
return;

q->dev = dev;
q->rpm_status = RPM_ACTIVE;
pm_runtime_set_autosuspend_delay(q->dev, -1);
Expand Down
4 changes: 2 additions & 2 deletions block/blk-mq-cpumap.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
static int cpu_to_queue_index(unsigned int nr_queues, const int cpu)
{
/*
* Non online CPU will be mapped to queue index 0.
* Non present CPU will be mapped to queue index 0.
*/
if (!cpu_online(cpu))
if (!cpu_present(cpu))
return 0;
return cpu % nr_queues;
}
Expand Down
18 changes: 13 additions & 5 deletions drivers/block/nbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -908,7 +908,8 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg)
continue;
}
sk_set_memalloc(sock->sk);
sock->sk->sk_sndtimeo = nbd->tag_set.timeout;
if (nbd->tag_set.timeout)
sock->sk->sk_sndtimeo = nbd->tag_set.timeout;
atomic_inc(&config->recv_threads);
refcount_inc(&nbd->config_refs);
old = nsock->sock;
Expand All @@ -922,6 +923,8 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg)
mutex_unlock(&nsock->tx_lock);
sockfd_put(old);

clear_bit(NBD_DISCONNECTED, &config->runtime_flags);

/* We take the tx_mutex in an error path in the recv_work, so we
* need to queue_work outside of the tx_mutex.
*/
Expand Down Expand Up @@ -978,11 +981,15 @@ static void send_disconnects(struct nbd_device *nbd)
int i, ret;

for (i = 0; i < config->num_connections; i++) {
struct nbd_sock *nsock = config->socks[i];

iov_iter_kvec(&from, WRITE | ITER_KVEC, &iov, 1, sizeof(request));
mutex_lock(&nsock->tx_lock);
ret = sock_xmit(nbd, i, 1, &from, 0, NULL);
if (ret <= 0)
dev_err(disk_to_dev(nbd->disk),
"Send disconnect failed %d\n", ret);
mutex_unlock(&nsock->tx_lock);
}
}

Expand All @@ -991,9 +998,8 @@ static int nbd_disconnect(struct nbd_device *nbd)
struct nbd_config *config = nbd->config;

dev_info(disk_to_dev(nbd->disk), "NBD_DISCONNECT\n");
if (!test_and_set_bit(NBD_DISCONNECT_REQUESTED,
&config->runtime_flags))
send_disconnects(nbd);
set_bit(NBD_DISCONNECT_REQUESTED, &config->runtime_flags);
send_disconnects(nbd);
return 0;
}

Expand Down Expand Up @@ -1074,7 +1080,9 @@ static int nbd_start_device(struct nbd_device *nbd)
return -ENOMEM;
}
sk_set_memalloc(config->socks[i]->sock->sk);
config->socks[i]->sock->sk->sk_sndtimeo = nbd->tag_set.timeout;
if (nbd->tag_set.timeout)
config->socks[i]->sock->sk->sk_sndtimeo =
nbd->tag_set.timeout;
atomic_inc(&config->recv_threads);
refcount_inc(&nbd->config_refs);
INIT_WORK(&args->work, recv_work);
Expand Down
25 changes: 14 additions & 11 deletions drivers/block/xen-blkfront.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ struct blk_shadow {
};

struct blkif_req {
int error;
blk_status_t error;
};

static inline struct blkif_req *blkif_req(struct request *rq)
Expand Down Expand Up @@ -708,6 +708,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
* existing persistent grants, or if we have to get new grants,
* as there are not sufficiently many free.
*/
bool new_persistent_gnts = false;
struct scatterlist *sg;
int num_sg, max_grefs, num_grant;

Expand All @@ -719,19 +720,21 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
*/
max_grefs += INDIRECT_GREFS(max_grefs);

/*
* We have to reserve 'max_grefs' grants because persistent
* grants are shared by all rings.
*/
if (max_grefs > 0)
if (gnttab_alloc_grant_references(max_grefs, &setup.gref_head) < 0) {
/* Check if we have enough persistent grants to allocate a requests */
if (rinfo->persistent_gnts_c < max_grefs) {
new_persistent_gnts = true;

if (gnttab_alloc_grant_references(
max_grefs - rinfo->persistent_gnts_c,
&setup.gref_head) < 0) {
gnttab_request_free_callback(
&rinfo->callback,
blkif_restart_queue_callback,
rinfo,
max_grefs);
max_grefs - rinfo->persistent_gnts_c);
return 1;
}
}

/* Fill out a communications ring structure. */
id = blkif_ring_get_request(rinfo, req, &ring_req);
Expand Down Expand Up @@ -832,7 +835,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
if (unlikely(require_extra_req))
rinfo->shadow[extra_id].req = *extra_ring_req;

if (max_grefs > 0)
if (new_persistent_gnts)
gnttab_free_grant_references(setup.gref_head);

return 0;
Expand Down Expand Up @@ -906,8 +909,8 @@ static blk_status_t blkif_queue_rq(struct blk_mq_hw_ctx *hctx,
return BLK_STS_IOERR;

out_busy:
spin_unlock_irqrestore(&rinfo->ring_lock, flags);
blk_mq_stop_hw_queue(hctx);
spin_unlock_irqrestore(&rinfo->ring_lock, flags);
return BLK_STS_RESOURCE;
}

Expand Down Expand Up @@ -1616,7 +1619,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
printk(KERN_WARNING "blkfront: %s: %s op failed\n",
info->gd->disk_name, op_name(bret->operation));
blkif_req(req)->error = -EOPNOTSUPP;
blkif_req(req)->error = BLK_STS_NOTSUPP;
}
if (unlikely(bret->status == BLKIF_RSP_ERROR &&
rinfo->shadow[id].req.u.rw.nr_segments == 0)) {
Expand Down
4 changes: 2 additions & 2 deletions drivers/lightnvm/pblk-rb.c
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ unsigned int pblk_rb_read_to_bio(struct pblk_rb *rb, struct nvm_rq *rqd,
* be directed to disk.
*/
int pblk_rb_copy_to_bio(struct pblk_rb *rb, struct bio *bio, sector_t lba,
struct ppa_addr ppa, int bio_iter)
struct ppa_addr ppa, int bio_iter, bool advanced_bio)
{
struct pblk *pblk = container_of(rb, struct pblk, rwb);
struct pblk_rb_entry *entry;
Expand Down Expand Up @@ -694,7 +694,7 @@ int pblk_rb_copy_to_bio(struct pblk_rb *rb, struct bio *bio, sector_t lba,
* filled with data from the cache). If part of the data resides on the
* media, we will read later on
*/
if (unlikely(!bio->bi_iter.bi_idx))
if (unlikely(!advanced_bio))
bio_advance(bio, bio_iter * PBLK_EXPOSED_PAGE_SIZE);

data = bio_data(bio);
Expand Down
23 changes: 16 additions & 7 deletions drivers/lightnvm/pblk-read.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,16 @@
*/
static int pblk_read_from_cache(struct pblk *pblk, struct bio *bio,
sector_t lba, struct ppa_addr ppa,
int bio_iter)
int bio_iter, bool advanced_bio)
{
#ifdef CONFIG_NVM_DEBUG
/* Callers must ensure that the ppa points to a cache address */
BUG_ON(pblk_ppa_empty(ppa));
BUG_ON(!pblk_addr_in_cache(ppa));
#endif

return pblk_rb_copy_to_bio(&pblk->rwb, bio, lba, ppa, bio_iter);
return pblk_rb_copy_to_bio(&pblk->rwb, bio, lba, ppa,
bio_iter, advanced_bio);
}

static void pblk_read_ppalist_rq(struct pblk *pblk, struct nvm_rq *rqd,
Expand All @@ -44,7 +45,7 @@ static void pblk_read_ppalist_rq(struct pblk *pblk, struct nvm_rq *rqd,
struct ppa_addr ppas[PBLK_MAX_REQ_ADDRS];
sector_t blba = pblk_get_lba(bio);
int nr_secs = rqd->nr_ppas;
int advanced_bio = 0;
bool advanced_bio = false;
int i, j = 0;

/* logic error: lba out-of-bounds. Ignore read request */
Expand All @@ -62,19 +63,26 @@ static void pblk_read_ppalist_rq(struct pblk *pblk, struct nvm_rq *rqd,
retry:
if (pblk_ppa_empty(p)) {
WARN_ON(test_and_set_bit(i, read_bitmap));
continue;

if (unlikely(!advanced_bio)) {
bio_advance(bio, (i) * PBLK_EXPOSED_PAGE_SIZE);
advanced_bio = true;
}

goto next;
}

/* Try to read from write buffer. The address is later checked
* on the write buffer to prevent retrieving overwritten data.
*/
if (pblk_addr_in_cache(p)) {
if (!pblk_read_from_cache(pblk, bio, lba, p, i)) {
if (!pblk_read_from_cache(pblk, bio, lba, p, i,
advanced_bio)) {
pblk_lookup_l2p_seq(pblk, &p, lba, 1);
goto retry;
}
WARN_ON(test_and_set_bit(i, read_bitmap));
advanced_bio = 1;
advanced_bio = true;
#ifdef CONFIG_NVM_DEBUG
atomic_long_inc(&pblk->cache_reads);
#endif
Expand All @@ -83,6 +91,7 @@ static void pblk_read_ppalist_rq(struct pblk *pblk, struct nvm_rq *rqd,
rqd->ppa_list[j++] = p;
}

next:
if (advanced_bio)
bio_advance(bio, PBLK_EXPOSED_PAGE_SIZE);
}
Expand Down Expand Up @@ -282,7 +291,7 @@ static void pblk_read_rq(struct pblk *pblk, struct nvm_rq *rqd,
* write buffer to prevent retrieving overwritten data.
*/
if (pblk_addr_in_cache(ppa)) {
if (!pblk_read_from_cache(pblk, bio, lba, ppa, 0)) {
if (!pblk_read_from_cache(pblk, bio, lba, ppa, 0, 1)) {
pblk_lookup_l2p_seq(pblk, &ppa, lba, 1);
goto retry;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/lightnvm/pblk.h
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ unsigned int pblk_rb_read_to_bio_list(struct pblk_rb *rb, struct bio *bio,
struct list_head *list,
unsigned int max);
int pblk_rb_copy_to_bio(struct pblk_rb *rb, struct bio *bio, sector_t lba,
struct ppa_addr ppa, int bio_iter);
struct ppa_addr ppa, int bio_iter, bool advanced_bio);
unsigned int pblk_rb_read_commit(struct pblk_rb *rb, unsigned int entries);

unsigned int pblk_rb_sync_init(struct pblk_rb *rb, unsigned long *flags);
Expand Down
6 changes: 5 additions & 1 deletion drivers/nvme/host/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1995,6 +1995,9 @@ static ssize_t wwid_show(struct device *dev, struct device_attribute *attr,
int serial_len = sizeof(ctrl->serial);
int model_len = sizeof(ctrl->model);

if (!uuid_is_null(&ns->uuid))
return sprintf(buf, "uuid.%pU\n", &ns->uuid);

if (memchr_inv(ns->nguid, 0, sizeof(ns->nguid)))
return sprintf(buf, "eui.%16phN\n", ns->nguid);

Expand Down Expand Up @@ -2709,7 +2712,8 @@ void nvme_kill_queues(struct nvme_ctrl *ctrl)
mutex_lock(&ctrl->namespaces_mutex);

/* Forcibly unquiesce queues to avoid blocking dispatch */
blk_mq_unquiesce_queue(ctrl->admin_q);
if (ctrl->admin_q)
blk_mq_unquiesce_queue(ctrl->admin_q);

list_for_each_entry(ns, &ctrl->namespaces, list) {
/*
Expand Down
Loading

0 comments on commit 0fa8dc4

Please sign in to comment.