diff options
| author | Jens Axboe <jens.axboe@oracle.com> | 2010-02-22 13:48:51 +0100 | 
|---|---|---|
| committer | Jens Axboe <jens.axboe@oracle.com> | 2010-02-22 13:48:51 +0100 | 
| commit | f11cbd74c5ff3614f6390b4de67a6ffdc614c378 (patch) | |
| tree | 6a30920ade9eeaac5bf6d6263b5d09712e882eb0 /block | |
| parent | 429c42c9d246f5bda868495c09974312a0177328 (diff) | |
| parent | aea187c46f7d03ce985e55eb1398d0776a15b928 (diff) | |
| download | linux-f11cbd74c5ff3614f6390b4de67a6ffdc614c378.tar.bz2 | |
Merge branch 'master' into for-2.6.34
Diffstat (limited to 'block')
| -rw-r--r-- | block/blk-cgroup.c | 4 | ||||
| -rw-r--r-- | block/cfq-iosched.c | 57 | 
2 files changed, 25 insertions, 36 deletions
| diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 1fa2654db0a6..e7dbbaf5fb3e 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -147,16 +147,16 @@ blkiocg_weight_write(struct cgroup *cgroup, struct cftype *cftype, u64 val)  		return -EINVAL;  	blkcg = cgroup_to_blkio_cgroup(cgroup); +	spin_lock(&blkio_list_lock);  	spin_lock_irq(&blkcg->lock);  	blkcg->weight = (unsigned int)val;  	hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node) { -		spin_lock(&blkio_list_lock);  		list_for_each_entry(blkiop, &blkio_list, list)  			blkiop->ops.blkio_update_group_weight_fn(blkg,  					blkcg->weight); -		spin_unlock(&blkio_list_lock);  	}  	spin_unlock_irq(&blkcg->lock); +	spin_unlock(&blkio_list_lock);  	return 0;  } diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 918c7fd9aeb1..023f4e69a337 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -42,16 +42,13 @@ static const int cfq_hist_divisor = 4;   */  #define CFQ_MIN_TT		(2) -/* - * Allow merged cfqqs to perform this amount of seeky I/O before - * deciding to break the queues up again. - */ -#define CFQQ_COOP_TOUT		(HZ) -  #define CFQ_SLICE_SCALE		(5)  #define CFQ_HW_QUEUE_MIN	(5)  #define CFQ_SERVICE_SHIFT       12 +#define CFQQ_SEEK_THR		8 * 1024 +#define CFQQ_SEEKY(cfqq)	((cfqq)->seek_mean > CFQQ_SEEK_THR) +  #define RQ_CIC(rq)		\  	((struct cfq_io_context *) (rq)->elevator_private)  #define RQ_CFQQ(rq)		(struct cfq_queue *) ((rq)->elevator_private2) @@ -137,7 +134,6 @@ struct cfq_queue {  	u64 seek_total;  	sector_t seek_mean;  	sector_t last_request_pos; -	unsigned long seeky_start;  	pid_t pid; @@ -314,6 +310,7 @@ enum cfqq_state_flags {  	CFQ_CFQQ_FLAG_slice_new,	/* no requests dispatched in slice */  	CFQ_CFQQ_FLAG_sync,		/* synchronous queue */  	CFQ_CFQQ_FLAG_coop,		/* cfqq is shared */ +	CFQ_CFQQ_FLAG_split_coop,	/* shared cfqq will be splitted */  	CFQ_CFQQ_FLAG_deep,		/* sync cfqq experienced large depth */  	CFQ_CFQQ_FLAG_wait_busy,	/* Waiting for next request */  }; @@ -342,6 +339,7 @@ CFQ_CFQQ_FNS(prio_changed);  CFQ_CFQQ_FNS(slice_new);  CFQ_CFQQ_FNS(sync);  CFQ_CFQQ_FNS(coop); +CFQ_CFQQ_FNS(split_coop);  CFQ_CFQQ_FNS(deep);  CFQ_CFQQ_FNS(wait_busy);  #undef CFQ_CFQQ_FNS @@ -1566,6 +1564,15 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,  	cfq_clear_cfqq_wait_busy(cfqq);  	/* +	 * If this cfqq is shared between multiple processes, check to +	 * make sure that those processes are still issuing I/Os within +	 * the mean seek distance.  If not, it may be time to break the +	 * queues apart again. +	 */ +	if (cfq_cfqq_coop(cfqq) && CFQQ_SEEKY(cfqq)) +		cfq_mark_cfqq_split_coop(cfqq); + +	/*  	 * store what was left of this slice, if the queue idled/timed out  	 */  	if (timed_out && !cfq_cfqq_slice_new(cfqq)) { @@ -1663,9 +1670,6 @@ static inline sector_t cfq_dist_from_last(struct cfq_data *cfqd,  		return cfqd->last_position - blk_rq_pos(rq);  } -#define CFQQ_SEEK_THR		8 * 1024 -#define CFQQ_SEEKY(cfqq)	((cfqq)->seek_mean > CFQQ_SEEK_THR) -  static inline int cfq_rq_close(struct cfq_data *cfqd, struct cfq_queue *cfqq,  			       struct request *rq, bool for_preempt)  { @@ -1803,7 +1807,7 @@ static bool cfq_should_idle(struct cfq_data *cfqd, struct cfq_queue *cfqq)  	 * Otherwise, we do only if they are the last ones  	 * in their service tree.  	 */ -	return service_tree->count == 1; +	return service_tree->count == 1 && cfq_cfqq_sync(cfqq);  }  static void cfq_arm_slice_timer(struct cfq_data *cfqd) @@ -3000,19 +3004,6 @@ cfq_update_io_seektime(struct cfq_data *cfqd, struct cfq_queue *cfqq,  	total = cfqq->seek_total + (cfqq->seek_samples/2);  	do_div(total, cfqq->seek_samples);  	cfqq->seek_mean = (sector_t)total; - -	/* -	 * If this cfqq is shared between multiple processes, check to -	 * make sure that those processes are still issuing I/Os within -	 * the mean seek distance.  If not, it may be time to break the -	 * queues apart again. -	 */ -	if (cfq_cfqq_coop(cfqq)) { -		if (CFQQ_SEEKY(cfqq) && !cfqq->seeky_start) -			cfqq->seeky_start = jiffies; -		else if (!CFQQ_SEEKY(cfqq)) -			cfqq->seeky_start = 0; -	}  }  /* @@ -3077,6 +3068,12 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,  		return true;  	/* +	 * Don't allow a non-RT request to preempt an ongoing RT cfqq timeslice. +	 */ +	if (cfq_class_rt(cfqq) && !cfq_class_rt(new_cfqq)) +		return false; + +	/*  	 * if the new request is sync, but the currently running queue is  	 * not, let the sync request have priority.  	 */ @@ -3447,14 +3444,6 @@ cfq_merge_cfqqs(struct cfq_data *cfqd, struct cfq_io_context *cic,  	return cic_to_cfqq(cic, 1);  } -static int should_split_cfqq(struct cfq_queue *cfqq) -{ -	if (cfqq->seeky_start && -	    time_after(jiffies, cfqq->seeky_start + CFQQ_COOP_TOUT)) -		return 1; -	return 0; -} -  /*   * Returns NULL if a new cfqq should be allocated, or the old cfqq if this   * was the last process referring to said cfqq. @@ -3463,9 +3452,9 @@ static struct cfq_queue *  split_cfqq(struct cfq_io_context *cic, struct cfq_queue *cfqq)  {  	if (cfqq_process_refs(cfqq) == 1) { -		cfqq->seeky_start = 0;  		cfqq->pid = current->pid;  		cfq_clear_cfqq_coop(cfqq); +		cfq_clear_cfqq_split_coop(cfqq);  		return cfqq;  	} @@ -3504,7 +3493,7 @@ new_queue:  		/*  		 * If the queue was seeky for too long, break it apart.  		 */ -		if (cfq_cfqq_coop(cfqq) && should_split_cfqq(cfqq)) { +		if (cfq_cfqq_coop(cfqq) && cfq_cfqq_split_coop(cfqq)) {  			cfq_log_cfqq(cfqd, cfqq, "breaking apart cfqq");  			cfqq = split_cfqq(cic, cfqq);  			if (!cfqq) |