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

Commit fb646385 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull block fixes from Jens Axboe:
 "Small collection of fixes that should go into this series. This pull
  contains:

   - NVMe pull request with three small fixes (via Christoph)

   - Kill useless NULL check before kmem_cache_destroy (Chengguang Xu)

   - Xen block driver pull request with persistent grant flushing fixes
     (Juergen Gross)

   - Final wbt fixes, wrapping up the changes for this series. These
     have been heavily tested (me)

   - cdrom info leak fix (Scott Bauer)

   - ATA dma quirk for SQ201 (Linus Walleij)

   - Straight forward bsg refcount_t conversion (John Pittman)"

* tag 'for-linus-20180830' of git://git.kernel.dk/linux-block:
  cdrom: Fix info leak/OOB read in cdrom_ioctl_drive_status
  nvmet: free workqueue object if module init fails
  nvme-fcloop: Fix dropped LS's to removed target port
  nvme-pci: add a memory barrier to nvme_dbbuf_update_and_check_event
  block: bsg: move atomic_t ref_count variable to refcount API
  block: remove unnecessary condition check
  ata: ftide010: Add a quirk for SQ201
  blk-wbt: remove dead code
  blk-wbt: improve waking of tasks
  blk-wbt: abstract out end IO completion handler
  xen/blkback: remove unused pers_gnts_lock from struct xen_blkif_ring
  xen/blkback: move persistent grants flags to bool
  xen/blkfront: reorder tests in xlblk_init()
  xen/blkfront: cleanup stale persistent grants
  xen/blkback: don't keep persistent grants too long
parents 9f8f16c8 52bd456a
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -15,3 +15,13 @@ Description:
                blkback. If the frontend tries to use more than
                max_persistent_grants, the LRU kicks in and starts
                removing 5% of max_persistent_grants every 100ms.

What:           /sys/module/xen_blkback/parameters/persistent_grant_unused_seconds
Date:           August 2018
KernelVersion:  4.19
Contact:        Roger Pau Monné <roger.pau@citrix.com>
Description:
                How long a persistent grant is allowed to remain
                allocated without being in use. The time is in
                seconds, 0 means indefinitely long.
                The default is 60 seconds.
+70 −19
Original line number Diff line number Diff line
@@ -123,16 +123,11 @@ static void rwb_wake_all(struct rq_wb *rwb)
	}
}

static void __wbt_done(struct rq_qos *rqos, enum wbt_flags wb_acct)
static void wbt_rqw_done(struct rq_wb *rwb, struct rq_wait *rqw,
			 enum wbt_flags wb_acct)
{
	struct rq_wb *rwb = RQWB(rqos);
	struct rq_wait *rqw;
	int inflight, limit;

	if (!(wb_acct & WBT_TRACKED))
		return;

	rqw = get_rq_wait(rwb, wb_acct);
	inflight = atomic_dec_return(&rqw->inflight);

	/*
@@ -166,10 +161,22 @@ static void __wbt_done(struct rq_qos *rqos, enum wbt_flags wb_acct)
		int diff = limit - inflight;

		if (!inflight || diff >= rwb->wb_background / 2)
			wake_up(&rqw->wait);
			wake_up_all(&rqw->wait);
	}
}

static void __wbt_done(struct rq_qos *rqos, enum wbt_flags wb_acct)
{
	struct rq_wb *rwb = RQWB(rqos);
	struct rq_wait *rqw;

	if (!(wb_acct & WBT_TRACKED))
		return;

	rqw = get_rq_wait(rwb, wb_acct);
	wbt_rqw_done(rwb, rqw, wb_acct);
}

/*
 * Called on completion of a request. Note that it's also called when
 * a request is merged, when the request gets freed.
@@ -481,6 +488,34 @@ static inline unsigned int get_limit(struct rq_wb *rwb, unsigned long rw)
	return limit;
}

struct wbt_wait_data {
	struct wait_queue_entry wq;
	struct task_struct *task;
	struct rq_wb *rwb;
	struct rq_wait *rqw;
	unsigned long rw;
	bool got_token;
};

static int wbt_wake_function(struct wait_queue_entry *curr, unsigned int mode,
			     int wake_flags, void *key)
{
	struct wbt_wait_data *data = container_of(curr, struct wbt_wait_data,
							wq);

	/*
	 * If we fail to get a budget, return -1 to interrupt the wake up
	 * loop in __wake_up_common.
	 */
	if (!rq_wait_inc_below(data->rqw, get_limit(data->rwb, data->rw)))
		return -1;

	data->got_token = true;
	list_del_init(&curr->entry);
	wake_up_process(data->task);
	return 1;
}

/*
 * Block if we will exceed our limit, or if we are currently waiting for
 * the timer to kick off queuing again.
@@ -491,19 +526,40 @@ static void __wbt_wait(struct rq_wb *rwb, enum wbt_flags wb_acct,
	__acquires(lock)
{
	struct rq_wait *rqw = get_rq_wait(rwb, wb_acct);
	DECLARE_WAITQUEUE(wait, current);
	struct wbt_wait_data data = {
		.wq = {
			.func	= wbt_wake_function,
			.entry	= LIST_HEAD_INIT(data.wq.entry),
		},
		.task = current,
		.rwb = rwb,
		.rqw = rqw,
		.rw = rw,
	};
	bool has_sleeper;

	has_sleeper = wq_has_sleeper(&rqw->wait);
	if (!has_sleeper && rq_wait_inc_below(rqw, get_limit(rwb, rw)))
		return;

	add_wait_queue_exclusive(&rqw->wait, &wait);
	prepare_to_wait_exclusive(&rqw->wait, &data.wq, TASK_UNINTERRUPTIBLE);
	do {
		set_current_state(TASK_UNINTERRUPTIBLE);
		if (data.got_token)
			break;

		if (!has_sleeper && rq_wait_inc_below(rqw, get_limit(rwb, rw)))
		if (!has_sleeper &&
		    rq_wait_inc_below(rqw, get_limit(rwb, rw))) {
			finish_wait(&rqw->wait, &data.wq);

			/*
			 * We raced with wbt_wake_function() getting a token,
			 * which means we now have two. Put our local token
			 * and wake anyone else potentially waiting for one.
			 */
			if (data.got_token)
				wbt_rqw_done(rwb, rqw, wb_acct);
			break;
		}

		if (lock) {
			spin_unlock_irq(lock);
@@ -511,11 +567,11 @@ static void __wbt_wait(struct rq_wb *rwb, enum wbt_flags wb_acct,
			spin_lock_irq(lock);
		} else
			io_schedule();

		has_sleeper = false;
	} while (1);

	__set_current_state(TASK_RUNNING);
	remove_wait_queue(&rqw->wait, &wait);
	finish_wait(&rqw->wait, &data.wq);
}

static inline bool wbt_should_throttle(struct rq_wb *rwb, struct bio *bio)
@@ -580,11 +636,6 @@ static void wbt_wait(struct rq_qos *rqos, struct bio *bio, spinlock_t *lock)
		return;
	}

	if (current_is_kswapd())
		flags |= WBT_KSWAPD;
	if (bio_op(bio) == REQ_OP_DISCARD)
		flags |= WBT_DISCARD;

	__wbt_wait(rwb, flags, bio->bi_opf, lock);

	if (!blk_stat_is_active(rwb->cb))
+4 −4
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ struct bsg_device {
	struct request_queue *queue;
	spinlock_t lock;
	struct hlist_node dev_list;
	atomic_t ref_count;
	refcount_t ref_count;
	char name[20];
	int max_queue;
};
@@ -252,7 +252,7 @@ static int bsg_put_device(struct bsg_device *bd)

	mutex_lock(&bsg_mutex);

	if (!atomic_dec_and_test(&bd->ref_count)) {
	if (!refcount_dec_and_test(&bd->ref_count)) {
		mutex_unlock(&bsg_mutex);
		return 0;
	}
@@ -290,7 +290,7 @@ static struct bsg_device *bsg_add_device(struct inode *inode,

	bd->queue = rq;

	atomic_set(&bd->ref_count, 1);
	refcount_set(&bd->ref_count, 1);
	hlist_add_head(&bd->dev_list, bsg_dev_idx_hash(iminor(inode)));

	strncpy(bd->name, dev_name(rq->bsg_dev.class_dev), sizeof(bd->name) - 1);
@@ -308,7 +308,7 @@ static struct bsg_device *__bsg_get_device(int minor, struct request_queue *q)

	hlist_for_each_entry(bd, bsg_dev_idx_hash(minor), dev_list) {
		if (bd->queue == q) {
			atomic_inc(&bd->ref_count);
			refcount_inc(&bd->ref_count);
			goto found;
		}
	}
+1 −2
Original line number Diff line number Diff line
@@ -895,7 +895,6 @@ int elv_register(struct elevator_type *e)
	spin_lock(&elv_list_lock);
	if (elevator_find(e->elevator_name, e->uses_mq)) {
		spin_unlock(&elv_list_lock);
		if (e->icq_cache)
		kmem_cache_destroy(e->icq_cache);
		return -EBUSY;
	}
+17 −10
Original line number Diff line number Diff line
@@ -256,14 +256,12 @@ static struct ata_port_operations pata_ftide010_port_ops = {
	.qc_issue	= ftide010_qc_issue,
};

static struct ata_port_info ftide010_port_info[] = {
	{
static struct ata_port_info ftide010_port_info = {
	.flags		= ATA_FLAG_SLAVE_POSS,
	.mwdma_mask	= ATA_MWDMA2,
	.udma_mask	= ATA_UDMA6,
	.pio_mask	= ATA_PIO4,
	.port_ops	= &pata_ftide010_port_ops,
	},
};

#if IS_ENABLED(CONFIG_SATA_GEMINI)
@@ -349,6 +347,7 @@ static int pata_ftide010_gemini_cable_detect(struct ata_port *ap)
}

static int pata_ftide010_gemini_init(struct ftide010 *ftide,
				     struct ata_port_info *pi,
				     bool is_ata1)
{
	struct device *dev = ftide->dev;
@@ -373,7 +372,13 @@ static int pata_ftide010_gemini_init(struct ftide010 *ftide,

	/* Flag port as SATA-capable */
	if (gemini_sata_bridge_enabled(sg, is_ata1))
		ftide010_port_info[0].flags |= ATA_FLAG_SATA;
		pi->flags |= ATA_FLAG_SATA;

	/* This device has broken DMA, only PIO works */
	if (of_machine_is_compatible("itian,sq201")) {
		pi->mwdma_mask = 0;
		pi->udma_mask = 0;
	}

	/*
	 * We assume that a simple 40-wire cable is used in the PATA mode.
@@ -435,6 +440,7 @@ static int pata_ftide010_gemini_init(struct ftide010 *ftide,
}
#else
static int pata_ftide010_gemini_init(struct ftide010 *ftide,
				     struct ata_port_info *pi,
				     bool is_ata1)
{
	return -ENOTSUPP;
@@ -446,7 +452,7 @@ static int pata_ftide010_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	const struct ata_port_info pi = ftide010_port_info[0];
	struct ata_port_info pi = ftide010_port_info;
	const struct ata_port_info *ppi[] = { &pi, NULL };
	struct ftide010 *ftide;
	struct resource *res;
@@ -490,6 +496,7 @@ static int pata_ftide010_probe(struct platform_device *pdev)
		 * are ATA0. This will also set up the cable types.
		 */
		ret = pata_ftide010_gemini_init(ftide,
				&pi,
				(res->start == 0x63400000));
		if (ret)
			goto err_dis_clk;
Loading