Unverified Commit 4ac8d141 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!903 backport block bugfix

Merge Pull Request from: @zhangjialin11 
 
This patch series fix block layer bug.
3 patchs fix iocost bug. Other patchs fix raid10 and badblocks bug.
 
 
Link:https://gitee.com/openeuler/kernel/pulls/903

 

Reviewed-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parents f0a5a36e b0ac58c9
Loading
Loading
Loading
Loading
+17 −12
Original line number Diff line number Diff line
@@ -165,7 +165,7 @@ int badblocks_set(struct badblocks *bb, sector_t s, int sectors,
{
	u64 *p;
	int lo, hi;
	int rv = 0;
	int rv = 0, changed = 0;
	unsigned long flags;

	if (bb->shift < 0)
@@ -230,6 +230,7 @@ int badblocks_set(struct badblocks *bb, sector_t s, int sectors,
				s = a + BB_MAX_LEN;
			}
			sectors = e - s;
			changed = 1;
		}
	}
	if (sectors && hi < bb->count) {
@@ -260,24 +261,24 @@ int badblocks_set(struct badblocks *bb, sector_t s, int sectors,
			sectors = e - s;
			lo = hi;
			hi++;
			changed = 1;
		}
	}
	if (sectors == 0 && hi < bb->count) {
		/* we might be able to combine lo and hi */
		/* Note: 's' is at the end of 'lo' */
		sector_t a = BB_OFFSET(p[hi]);
		int lolen = BB_LEN(p[lo]);
		int hilen = BB_LEN(p[hi]);
		int newlen = lolen + hilen - (s - a);
		sector_t a = BB_OFFSET(p[lo]);
		int newlen = max(s, BB_OFFSET(p[hi]) + BB_LEN(p[hi])) - a;

		if (s >= a && newlen < BB_MAX_LEN) {
		if (s >= BB_OFFSET(p[hi]) && newlen < BB_MAX_LEN) {
			/* yes, we can combine them */
			int ack = BB_ACK(p[lo]) && BB_ACK(p[hi]);

			p[lo] = BB_MAKE(BB_OFFSET(p[lo]), newlen, ack);
			p[lo] = BB_MAKE(a, newlen, ack);
			memmove(p + hi, p + hi + 1,
				(bb->count - hi - 1) * 8);
			bb->count--;
			changed = 1;
		}
	}
	while (sectors) {
@@ -300,14 +301,18 @@ int badblocks_set(struct badblocks *bb, sector_t s, int sectors,
			p[hi] = BB_MAKE(s, this_sectors, acknowledged);
			sectors -= this_sectors;
			s += this_sectors;
			hi++;
			changed = 1;
		}
	}

	bb->changed = 1;
	if (changed) {
		bb->changed = changed;
		if (!acknowledged)
			bb->unacked_exist = 1;
		else
			badblocks_update_acked(bb);
	}
	write_sequnlock_irqrestore(&bb->lock, flags);

	return rv;
+25 −10
Original line number Diff line number Diff line
@@ -2414,6 +2414,7 @@ static u64 adjust_inuse_and_calc_cost(struct ioc_gq *iocg, u64 vtime,
	u32 hwi, adj_step;
	s64 margin;
	u64 cost, new_inuse;
	unsigned long flags;

	current_hweight(iocg, NULL, &hwi);
	old_hwi = hwi;
@@ -2432,11 +2433,11 @@ static u64 adjust_inuse_and_calc_cost(struct ioc_gq *iocg, u64 vtime,
	    iocg->inuse == iocg->active)
		return cost;

	spin_lock_irq(&ioc->lock);
	spin_lock_irqsave(&ioc->lock, flags);

	/* we own inuse only when @iocg is in the normal active state */
	if (iocg->abs_vdebt || list_empty(&iocg->active_list)) {
		spin_unlock_irq(&ioc->lock);
		spin_unlock_irqrestore(&ioc->lock, flags);
		return cost;
	}

@@ -2457,7 +2458,7 @@ static u64 adjust_inuse_and_calc_cost(struct ioc_gq *iocg, u64 vtime,
	} while (time_after64(vtime + cost, now->vnow) &&
		 iocg->inuse != iocg->active);

	spin_unlock_irq(&ioc->lock);
	spin_unlock_irqrestore(&ioc->lock, flags);

	TRACE_IOCG_PATH(inuse_adjust, iocg, now,
			old_inuse, iocg->inuse, old_hwi, hwi);
@@ -2873,16 +2874,22 @@ static int blk_iocost_init(struct request_queue *q)
	 * called before policy activation completion, can't assume that the
	 * target bio has an iocg associated and need to test for NULL iocg.
	 */
	rq_qos_add(q, rqos);
	ret = rq_qos_add(q, rqos);
	if (ret)
		goto err_free_ioc;

	ret = blkcg_activate_policy(q, &blkcg_policy_iocost);
	if (ret) {
	if (ret)
		goto err_del_qos;
	return 0;

err_del_qos:
	rq_qos_del(q, rqos);
err_free_ioc:
	free_percpu(ioc->pcpu_stat);
	kfree(ioc);
	return ret;
}
	return 0;
}

static struct blkcg_policy_data *ioc_cpd_alloc(gfp_t gfp)
{
@@ -3166,6 +3173,10 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
	disk = blkcg_conf_get_disk(&input);
	if (IS_ERR(disk))
		return PTR_ERR(disk);
	if (!queue_is_mq(disk->queue)) {
		ret = -EOPNOTSUPP;
		goto err;
	}

	ioc = q_to_ioc(disk->queue);
	if (!ioc) {
@@ -3333,6 +3344,10 @@ static ssize_t ioc_cost_model_write(struct kernfs_open_file *of, char *input,
	disk = blkcg_conf_get_disk(&input);
	if (IS_ERR(disk))
		return PTR_ERR(disk);
	if (!queue_is_mq(disk->queue)) {
		ret = -EOPNOTSUPP;
		goto err;
	}

	ioc = q_to_ioc(disk->queue);
	if (!ioc) {
+11 −7
Original line number Diff line number Diff line
@@ -772,19 +772,23 @@ int blk_iolatency_init(struct request_queue *q)
	rqos->ops = &blkcg_iolatency_ops;
	rqos->q = q;

	rq_qos_add(q, rqos);

	ret = rq_qos_add(q, rqos);
	if (ret)
		goto err_free;
	ret = blkcg_activate_policy(q, &blkcg_policy_iolatency);
	if (ret) {
		rq_qos_del(q, rqos);
		kfree(blkiolat);
		return ret;
	}
	if (ret)
		goto err_qos_del;

	timer_setup(&blkiolat->timer, blkiolatency_timer_fn, 0);
	INIT_WORK(&blkiolat->enable_work, blkiolatency_enable_work_fn);

	return 0;

err_qos_del:
	rq_qos_del(q, rqos);
err_free:
	kfree(blkiolat);
	return ret;
}

static void iolatency_set_min_lat_nsec(struct blkcg_gq *blkg, u64 val)
+10 −1
Original line number Diff line number Diff line
@@ -98,7 +98,7 @@ static inline void rq_wait_init(struct rq_wait *rq_wait)
	init_waitqueue_head(&rq_wait->wait);
}

static inline void rq_qos_add(struct request_queue *q, struct rq_qos *rqos)
static inline int rq_qos_add(struct request_queue *q, struct rq_qos *rqos)
{
	/*
	 * No IO can be in-flight when adding rqos, so freeze queue, which
@@ -110,6 +110,8 @@ static inline void rq_qos_add(struct request_queue *q, struct rq_qos *rqos)
	blk_mq_freeze_queue(q);

	spin_lock_irq(&q->queue_lock);
	if (rq_qos_id(q, rqos->id))
		goto ebusy;
	rqos->next = q->rq_qos;
	q->rq_qos = rqos;
	spin_unlock_irq(&q->queue_lock);
@@ -118,6 +120,13 @@ static inline void rq_qos_add(struct request_queue *q, struct rq_qos *rqos)

	if (rqos->ops->debugfs_attrs)
		blk_mq_debugfs_register_rqos(rqos);

	return 0;
ebusy:
	spin_unlock_irq(&q->queue_lock);
	blk_mq_unfreeze_queue(q);
	return -EBUSY;

}

static inline void rq_qos_del(struct request_queue *q, struct rq_qos *rqos)
+11 −1
Original line number Diff line number Diff line
@@ -818,6 +818,7 @@ int wbt_init(struct request_queue *q)
{
	struct rq_wb *rwb;
	int i;
	int ret;

	rwb = kzalloc(sizeof(*rwb), GFP_KERNEL);
	if (!rwb)
@@ -847,8 +848,17 @@ int wbt_init(struct request_queue *q)
	/*
	 * Assign rwb and add the stats callback.
	 */
	rq_qos_add(q, &rwb->rqos);
	ret = rq_qos_add(q, &rwb->rqos);
	if (ret)
		goto err_free;

	blk_stat_add_callback(q, rwb->cb);

	return 0;

err_free:
	blk_stat_free_callback(rwb->cb);
	kfree(rwb);
	return ret;

}
Loading