@ -1522,6 +1522,9 @@ static void cfq_init_cfqg_base(struct cfq_group *cfqg)
}
# ifdef CONFIG_CFQ_GROUP_IOSCHED
static int __cfq_set_weight ( struct cgroup_subsys_state * css , u64 val ,
bool on_dfl , bool reset_dev , bool is_leaf_weight ) ;
static void cfqg_stats_exit ( struct cfqg_stats * stats )
{
blkg_rwstat_exit ( & stats - > merged ) ;
@ -1578,14 +1581,14 @@ static struct blkcg_policy_data *cfq_cpd_alloc(gfp_t gfp)
static void cfq_cpd_init ( struct blkcg_policy_data * cpd )
{
struct cfq_group_data * cgd = cpd_to_cfqgd ( cpd ) ;
unsigned int weight = cgroup_on_dfl ( blkcg_root . css . cgroup ) ?
CGROUP_WEIGHT_DFL : CFQ_WEIGHT_LEGACY_DFL ;
if ( cpd_to_blkcg ( cpd ) = = & blkcg_root ) {
cgd - > weight = 2 * CFQ_WEIGHT_LEGACY_DFL ;
cgd - > leaf_weight = 2 * CFQ_WEIGHT_LEGACY_DFL ;
} else {
cgd - > weight = CFQ_WEIGHT_LEGACY_DFL ;
cgd - > leaf_weight = CFQ_WEIGHT_LEGACY_DFL ;
}
if ( cpd_to_blkcg ( cpd ) = = & blkcg_root )
weight * = 2 ;
cgd - > weight = weight ;
cgd - > leaf_weight = weight ;
}
static void cfq_cpd_free ( struct blkcg_policy_data * cpd )
@ -1593,6 +1596,19 @@ static void cfq_cpd_free(struct blkcg_policy_data *cpd)
kfree ( cpd_to_cfqgd ( cpd ) ) ;
}
static void cfq_cpd_bind ( struct blkcg_policy_data * cpd )
{
struct blkcg * blkcg = cpd_to_blkcg ( cpd ) ;
bool on_dfl = cgroup_on_dfl ( blkcg_root . css . cgroup ) ;
unsigned int weight = on_dfl ? CGROUP_WEIGHT_DFL : CFQ_WEIGHT_LEGACY_DFL ;
if ( blkcg = = & blkcg_root )
weight * = 2 ;
WARN_ON_ONCE ( __cfq_set_weight ( & blkcg - > css , weight , on_dfl , true , false ) ) ;
WARN_ON_ONCE ( __cfq_set_weight ( & blkcg - > css , weight , on_dfl , true , true ) ) ;
}
static struct blkg_policy_data * cfq_pd_alloc ( gfp_t gfp , int node )
{
struct cfq_group * cfqg ;
@ -1742,6 +1758,8 @@ static ssize_t __cfqg_set_weight_device(struct kernfs_open_file *of,
char * buf , size_t nbytes , loff_t off ,
bool on_dfl , bool is_leaf_weight )
{
unsigned int min = on_dfl ? CGROUP_WEIGHT_MIN : CFQ_WEIGHT_LEGACY_MIN ;
unsigned int max = on_dfl ? CGROUP_WEIGHT_MAX : CFQ_WEIGHT_LEGACY_MAX ;
struct blkcg * blkcg = css_to_blkcg ( of_css ( of ) ) ;
struct blkg_conf_ctx ctx ;
struct cfq_group * cfqg ;
@ -1769,7 +1787,7 @@ static ssize_t __cfqg_set_weight_device(struct kernfs_open_file *of,
cfqgd = blkcg_to_cfqgd ( blkcg ) ;
ret = - ERANGE ;
if ( ! v | | ( v > = CFQ_WEIGHT_LEGACY_MIN & & v < = CFQ_WEIGHT_LEGACY_MAX ) ) {
if ( ! v | | ( v > = min & & v < = max ) ) {
if ( ! is_leaf_weight ) {
cfqg - > dev_weight = v ;
cfqg - > new_weight = v ? : cfqgd - > weight ;
@ -1797,15 +1815,17 @@ static ssize_t cfqg_set_leaf_weight_device(struct kernfs_open_file *of,
}
static int __cfq_set_weight ( struct cgroup_subsys_state * css , u64 val ,
bool is_leaf_weight )
bool on_dfl , bool reset_dev , bool is_leaf_weight )
{
unsigned int min = on_dfl ? CGROUP_WEIGHT_MIN : CFQ_WEIGHT_LEGACY_MIN ;
unsigned int max = on_dfl ? CGROUP_WEIGHT_MAX : CFQ_WEIGHT_LEGACY_MAX ;
struct blkcg * blkcg = css_to_blkcg ( css ) ;
struct blkcg_gq * blkg ;
struct cfq_group_data * cfqgd ;
int ret = 0 ;
if ( val < CFQ_WEIGHT_LEGACY_MIN | | val > CFQ_WEIGHT_LEGACY_MAX )
return - EINVAL ;
if ( val < min | | val > max )
return - ERANGE ;
spin_lock_irq ( & blkcg - > lock ) ;
cfqgd = blkcg_to_cfqgd ( blkcg ) ;
@ -1826,9 +1846,13 @@ static int __cfq_set_weight(struct cgroup_subsys_state *css, u64 val,
continue ;
if ( ! is_leaf_weight ) {
if ( reset_dev )
cfqg - > dev_weight = 0 ;
if ( ! cfqg - > dev_weight )
cfqg - > new_weight = cfqgd - > weight ;
} else {
if ( reset_dev )
cfqg - > dev_leaf_weight = 0 ;
if ( ! cfqg - > dev_leaf_weight )
cfqg - > new_leaf_weight = cfqgd - > leaf_weight ;
}
@ -1842,13 +1866,13 @@ out:
static int cfq_set_weight ( struct cgroup_subsys_state * css , struct cftype * cft ,
u64 val )
{
return __cfq_set_weight ( css , val , false ) ;
return __cfq_set_weight ( css , val , false , false , false ) ;
}
static int cfq_set_leaf_weight ( struct cgroup_subsys_state * css ,
struct cftype * cft , u64 val )
{
return __cfq_set_weight ( css , val , true ) ;
return __cfq_set_weight ( css , val , false , false , true ) ;
}
static int cfqg_print_stat ( struct seq_file * sf , void * v )
@ -2135,7 +2159,7 @@ static ssize_t cfq_set_weight_on_dfl(struct kernfs_open_file *of,
/* "WEIGHT" or "default WEIGHT" sets the default weight */
v = simple_strtoull ( buf , & endp , 0 ) ;
if ( * endp = = ' \0 ' | | sscanf ( buf , " default %llu " , & v ) = = 1 ) {
ret = __cfq_set_weight ( of_css ( of ) , v , false ) ;
ret = __cfq_set_weight ( of_css ( of ) , v , true , false , false ) ;
return ret ? : nbytes ;
}
@ -4512,9 +4536,9 @@ static int cfq_init_queue(struct request_queue *q, struct elevator_type *e)
goto out_free ;
cfq_init_cfqg_base ( cfqd - > root_group ) ;
# endif
cfqd - > root_group - > weight = 2 * CFQ_WEIGHT_LEGACY_DFL ;
cfqd - > root_group - > leaf_weight = 2 * CFQ_WEIGHT_LEGACY_DFL ;
# endif
/*
* Not strictly needed ( since RB_ROOT just clears the node and we
@ -4715,6 +4739,7 @@ static struct blkcg_policy blkcg_policy_cfq = {
. cpd_alloc_fn = cfq_cpd_alloc ,
. cpd_init_fn = cfq_cpd_init ,
. cpd_free_fn = cfq_cpd_free ,
. cpd_bind_fn = cfq_cpd_bind ,
. pd_alloc_fn = cfq_pd_alloc ,
. pd_init_fn = cfq_pd_init ,