소스 검색

blk-wbt: allow wbt to be enabled always through sysfs

Currently there's no way to enable wbt if it's not enabled in the
kernel config by default for a device. Allow a write to the
'wbt_lat_usec' queue sysfs file to enable wbt.

This is useful for both the kernel config case, but also if the
device is CFQ managed and it was turned off by default.

Signed-off-by: Jens Axboe <axboe@fb.com>
Jens Axboe 8 년 전
부모
커밋
d62118b6dd
3개의 변경된 파일29개의 추가작업 그리고 7개의 파일을 삭제
  1. 16 6
      block/blk-sysfs.c
  2. 2 1
      block/blk-wbt.c
  3. 11 0
      block/blk-wbt.h

+ 16 - 6
block/blk-sysfs.c

@@ -425,20 +425,30 @@ static ssize_t queue_wb_lat_store(struct request_queue *q, const char *page,
 	ssize_t ret;
 	ssize_t ret;
 	s64 val;
 	s64 val;
 
 
-	rwb = q->rq_wb;
-	if (!rwb)
-		return -EINVAL;
-
 	ret = queue_var_store64(&val, page);
 	ret = queue_var_store64(&val, page);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
+	if (val < -1)
+		return -EINVAL;
+
+	rwb = q->rq_wb;
+	if (!rwb) {
+		ret = wbt_init(q);
+		if (ret)
+			return ret;
+
+		rwb = q->rq_wb;
+		if (!rwb)
+			return -EINVAL;
+	}
 
 
 	if (val == -1)
 	if (val == -1)
 		rwb->min_lat_nsec = wbt_default_latency_nsec(q);
 		rwb->min_lat_nsec = wbt_default_latency_nsec(q);
 	else if (val >= 0)
 	else if (val >= 0)
 		rwb->min_lat_nsec = val * 1000ULL;
 		rwb->min_lat_nsec = val * 1000ULL;
-	else
-		return -EINVAL;
+
+	if (rwb->enable_state == WBT_STATE_ON_DEFAULT)
+		rwb->enable_state = WBT_STATE_ON_MANUAL;
 
 
 	wbt_update_limits(rwb);
 	wbt_update_limits(rwb);
 	return count;
 	return count;

+ 2 - 1
block/blk-wbt.c

@@ -673,7 +673,7 @@ void wbt_disable_default(struct request_queue *q)
 {
 {
 	struct rq_wb *rwb = q->rq_wb;
 	struct rq_wb *rwb = q->rq_wb;
 
 
-	if (rwb) {
+	if (rwb && rwb->enable_state == WBT_STATE_ON_DEFAULT) {
 		del_timer_sync(&rwb->window_timer);
 		del_timer_sync(&rwb->window_timer);
 		rwb->win_nsec = rwb->min_lat_nsec = 0;
 		rwb->win_nsec = rwb->min_lat_nsec = 0;
 		wbt_update_limits(rwb);
 		wbt_update_limits(rwb);
@@ -721,6 +721,7 @@ int wbt_init(struct request_queue *q)
 	rwb->last_comp = rwb->last_issue = jiffies;
 	rwb->last_comp = rwb->last_issue = jiffies;
 	rwb->queue = q;
 	rwb->queue = q;
 	rwb->win_nsec = RWB_WINDOW_NSEC;
 	rwb->win_nsec = RWB_WINDOW_NSEC;
+	rwb->enable_state = WBT_STATE_ON_DEFAULT;
 	wbt_update_limits(rwb);
 	wbt_update_limits(rwb);
 
 
 	/*
 	/*

+ 11 - 0
block/blk-wbt.h

@@ -21,6 +21,15 @@ enum {
 	WBT_NUM_RWQ		= 2,
 	WBT_NUM_RWQ		= 2,
 };
 };
 
 
+/*
+ * Enable states. Either off, or on by default (done at init time),
+ * or on through manual setup in sysfs.
+ */
+enum {
+	WBT_STATE_ON_DEFAULT	= 1,
+	WBT_STATE_ON_MANUAL	= 2,
+};
+
 static inline void wbt_clear_state(struct blk_issue_stat *stat)
 static inline void wbt_clear_state(struct blk_issue_stat *stat)
 {
 {
 	stat->time &= BLK_STAT_TIME_MASK;
 	stat->time &= BLK_STAT_TIME_MASK;
@@ -61,6 +70,8 @@ struct rq_wb {
 	int scale_step;
 	int scale_step;
 	bool scaled_max;
 	bool scaled_max;
 
 
+	short enable_state;			/* WBT_STATE_* */
+
 	/*
 	/*
 	 * Number of consecutive periods where we don't have enough
 	 * Number of consecutive periods where we don't have enough
 	 * information to make a firm scale up/down decision.
 	 * information to make a firm scale up/down decision.