29
29
30
30
#define MAX_KEY_LEN 100
31
31
32
+ /*
33
+ * blkcg_pol_mutex protects blkcg_policy[] and policy [de]activation.
34
+ * blkcg_pol_register_mutex nests outside of it and synchronizes entire
35
+ * policy [un]register operations including cgroup file additions /
36
+ * removals. Putting cgroup file registration outside blkcg_pol_mutex
37
+ * allows grabbing it from cgroup callbacks.
38
+ */
39
+ static DEFINE_MUTEX (blkcg_pol_register_mutex );
32
40
static DEFINE_MUTEX (blkcg_pol_mutex );
33
41
34
42
struct blkcg blkcg_root ;
@@ -38,6 +46,8 @@ struct cgroup_subsys_state * const blkcg_root_css = &blkcg_root.css;
38
46
39
47
static struct blkcg_policy * blkcg_policy [BLKCG_MAX_POLS ];
40
48
49
+ static LIST_HEAD (all_blkcgs ); /* protected by blkcg_pol_mutex */
50
+
41
51
static bool blkcg_policy_enabled (struct request_queue * q ,
42
52
const struct blkcg_policy * pol )
43
53
{
@@ -453,20 +463,7 @@ static int blkcg_reset_stats(struct cgroup_subsys_state *css,
453
463
struct blkcg_gq * blkg ;
454
464
int i ;
455
465
456
- /*
457
- * XXX: We invoke cgroup_add/rm_cftypes() under blkcg_pol_mutex
458
- * which ends up putting cgroup's internal cgroup_tree_mutex under
459
- * it; however, cgroup_tree_mutex is nested above cgroup file
460
- * active protection and grabbing blkcg_pol_mutex from a cgroup
461
- * file operation creates a possible circular dependency. cgroup
462
- * internal locking is planned to go through further simplification
463
- * and this issue should go away soon. For now, let's trylock
464
- * blkcg_pol_mutex and restart the write on failure.
465
- *
466
- * http://lkml.kernel.org/g/5363C04B.4010400@oracle.com
467
- */
468
- if (!mutex_trylock (& blkcg_pol_mutex ))
469
- return restart_syscall ();
466
+ mutex_lock (& blkcg_pol_mutex );
470
467
spin_lock_irq (& blkcg -> lock );
471
468
472
469
/*
@@ -822,8 +819,17 @@ static void blkcg_css_free(struct cgroup_subsys_state *css)
822
819
{
823
820
struct blkcg * blkcg = css_to_blkcg (css );
824
821
825
- if (blkcg != & blkcg_root )
822
+ mutex_lock (& blkcg_pol_mutex );
823
+ list_del (& blkcg -> all_blkcgs_node );
824
+ mutex_unlock (& blkcg_pol_mutex );
825
+
826
+ if (blkcg != & blkcg_root ) {
827
+ int i ;
828
+
829
+ for (i = 0 ; i < BLKCG_MAX_POLS ; i ++ )
830
+ kfree (blkcg -> pd [i ]);
826
831
kfree (blkcg );
832
+ }
827
833
}
828
834
829
835
static struct cgroup_subsys_state *
@@ -833,6 +839,8 @@ blkcg_css_alloc(struct cgroup_subsys_state *parent_css)
833
839
struct cgroup_subsys_state * ret ;
834
840
int i ;
835
841
842
+ mutex_lock (& blkcg_pol_mutex );
843
+
836
844
if (!parent_css ) {
837
845
blkcg = & blkcg_root ;
838
846
goto done ;
@@ -875,14 +883,17 @@ blkcg_css_alloc(struct cgroup_subsys_state *parent_css)
875
883
#ifdef CONFIG_CGROUP_WRITEBACK
876
884
INIT_LIST_HEAD (& blkcg -> cgwb_list );
877
885
#endif
886
+ list_add_tail (& blkcg -> all_blkcgs_node , & all_blkcgs );
887
+
888
+ mutex_unlock (& blkcg_pol_mutex );
878
889
return & blkcg -> css ;
879
890
880
891
free_pd_blkcg :
881
892
for (i -- ; i >= 0 ; i -- )
882
893
kfree (blkcg -> pd [i ]);
883
-
884
894
free_blkcg :
885
895
kfree (blkcg );
896
+ mutex_unlock (& blkcg_pol_mutex );
886
897
return ret ;
887
898
}
888
899
@@ -1037,10 +1048,8 @@ int blkcg_activate_policy(struct request_queue *q,
1037
1048
const struct blkcg_policy * pol )
1038
1049
{
1039
1050
LIST_HEAD (pds );
1040
- LIST_HEAD (cpds );
1041
1051
struct blkcg_gq * blkg ;
1042
1052
struct blkg_policy_data * pd , * nd ;
1043
- struct blkcg_policy_data * cpd , * cnd ;
1044
1053
int cnt = 0 , ret ;
1045
1054
1046
1055
if (blkcg_policy_enabled (q , pol ))
@@ -1053,26 +1062,14 @@ int blkcg_activate_policy(struct request_queue *q,
1053
1062
cnt ++ ;
1054
1063
spin_unlock_irq (q -> queue_lock );
1055
1064
1056
- /*
1057
- * Allocate per-blkg and per-blkcg policy data
1058
- * for all existing blkgs.
1059
- */
1065
+ /* allocate per-blkg policy data for all existing blkgs */
1060
1066
while (cnt -- ) {
1061
1067
pd = kzalloc_node (pol -> pd_size , GFP_KERNEL , q -> node );
1062
1068
if (!pd ) {
1063
1069
ret = - ENOMEM ;
1064
1070
goto out_free ;
1065
1071
}
1066
1072
list_add_tail (& pd -> alloc_node , & pds );
1067
-
1068
- if (!pol -> cpd_size )
1069
- continue ;
1070
- cpd = kzalloc_node (pol -> cpd_size , GFP_KERNEL , q -> node );
1071
- if (!cpd ) {
1072
- ret = - ENOMEM ;
1073
- goto out_free ;
1074
- }
1075
- list_add_tail (& cpd -> alloc_node , & cpds );
1076
1073
}
1077
1074
1078
1075
/*
@@ -1082,32 +1079,17 @@ int blkcg_activate_policy(struct request_queue *q,
1082
1079
spin_lock_irq (q -> queue_lock );
1083
1080
1084
1081
list_for_each_entry (blkg , & q -> blkg_list , q_node ) {
1085
- if (WARN_ON (list_empty (& pds )) ||
1086
- WARN_ON (pol -> cpd_size && list_empty (& cpds ))) {
1082
+ if (WARN_ON (list_empty (& pds ))) {
1087
1083
/* umm... this shouldn't happen, just abort */
1088
1084
ret = - ENOMEM ;
1089
1085
goto out_unlock ;
1090
1086
}
1091
- cpd = list_first_entry (& cpds , struct blkcg_policy_data ,
1092
- alloc_node );
1093
- list_del_init (& cpd -> alloc_node );
1094
1087
pd = list_first_entry (& pds , struct blkg_policy_data , alloc_node );
1095
1088
list_del_init (& pd -> alloc_node );
1096
1089
1097
1090
/* grab blkcg lock too while installing @pd on @blkg */
1098
1091
spin_lock (& blkg -> blkcg -> lock );
1099
1092
1100
- if (!pol -> cpd_size )
1101
- goto no_cpd ;
1102
- if (!blkg -> blkcg -> pd [pol -> plid ]) {
1103
- /* Per-policy per-blkcg data */
1104
- blkg -> blkcg -> pd [pol -> plid ] = cpd ;
1105
- cpd -> plid = pol -> plid ;
1106
- pol -> cpd_init_fn (blkg -> blkcg );
1107
- } else { /* must free it as it has already been extracted */
1108
- kfree (cpd );
1109
- }
1110
- no_cpd :
1111
1093
blkg -> pd [pol -> plid ] = pd ;
1112
1094
pd -> blkg = blkg ;
1113
1095
pd -> plid = pol -> plid ;
@@ -1124,8 +1106,6 @@ int blkcg_activate_policy(struct request_queue *q,
1124
1106
blk_queue_bypass_end (q );
1125
1107
list_for_each_entry_safe (pd , nd , & pds , alloc_node )
1126
1108
kfree (pd );
1127
- list_for_each_entry_safe (cpd , cnd , & cpds , alloc_node )
1128
- kfree (cpd );
1129
1109
return ret ;
1130
1110
}
1131
1111
EXPORT_SYMBOL_GPL (blkcg_activate_policy );
@@ -1162,8 +1142,6 @@ void blkcg_deactivate_policy(struct request_queue *q,
1162
1142
1163
1143
kfree (blkg -> pd [pol -> plid ]);
1164
1144
blkg -> pd [pol -> plid ] = NULL ;
1165
- kfree (blkg -> blkcg -> pd [pol -> plid ]);
1166
- blkg -> blkcg -> pd [pol -> plid ] = NULL ;
1167
1145
1168
1146
spin_unlock (& blkg -> blkcg -> lock );
1169
1147
}
@@ -1182,11 +1160,13 @@ EXPORT_SYMBOL_GPL(blkcg_deactivate_policy);
1182
1160
*/
1183
1161
int blkcg_policy_register (struct blkcg_policy * pol )
1184
1162
{
1163
+ struct blkcg * blkcg ;
1185
1164
int i , ret ;
1186
1165
1187
1166
if (WARN_ON (pol -> pd_size < sizeof (struct blkg_policy_data )))
1188
1167
return - EINVAL ;
1189
1168
1169
+ mutex_lock (& blkcg_pol_register_mutex );
1190
1170
mutex_lock (& blkcg_pol_mutex );
1191
1171
1192
1172
/* find an empty slot */
@@ -1195,19 +1175,49 @@ int blkcg_policy_register(struct blkcg_policy *pol)
1195
1175
if (!blkcg_policy [i ])
1196
1176
break ;
1197
1177
if (i >= BLKCG_MAX_POLS )
1198
- goto out_unlock ;
1178
+ goto err_unlock ;
1199
1179
1200
- /* register and update blkgs */
1180
+ /* register @pol */
1201
1181
pol -> plid = i ;
1202
- blkcg_policy [i ] = pol ;
1182
+ blkcg_policy [pol -> plid ] = pol ;
1183
+
1184
+ /* allocate and install cpd's */
1185
+ if (pol -> cpd_size ) {
1186
+ list_for_each_entry (blkcg , & all_blkcgs , all_blkcgs_node ) {
1187
+ struct blkcg_policy_data * cpd ;
1188
+
1189
+ cpd = kzalloc (pol -> cpd_size , GFP_KERNEL );
1190
+ if (!cpd ) {
1191
+ mutex_unlock (& blkcg_pol_mutex );
1192
+ goto err_free_cpds ;
1193
+ }
1194
+
1195
+ blkcg -> pd [pol -> plid ] = cpd ;
1196
+ cpd -> plid = pol -> plid ;
1197
+ pol -> cpd_init_fn (blkcg );
1198
+ }
1199
+ }
1200
+
1201
+ mutex_unlock (& blkcg_pol_mutex );
1203
1202
1204
1203
/* everything is in place, add intf files for the new policy */
1205
1204
if (pol -> cftypes )
1206
1205
WARN_ON (cgroup_add_legacy_cftypes (& blkio_cgrp_subsys ,
1207
1206
pol -> cftypes ));
1208
- ret = 0 ;
1209
- out_unlock :
1207
+ mutex_unlock (& blkcg_pol_register_mutex );
1208
+ return 0 ;
1209
+
1210
+ err_free_cpds :
1211
+ if (pol -> cpd_size ) {
1212
+ list_for_each_entry (blkcg , & all_blkcgs , all_blkcgs_node ) {
1213
+ kfree (blkcg -> pd [pol -> plid ]);
1214
+ blkcg -> pd [pol -> plid ] = NULL ;
1215
+ }
1216
+ }
1217
+ blkcg_policy [pol -> plid ] = NULL ;
1218
+ err_unlock :
1210
1219
mutex_unlock (& blkcg_pol_mutex );
1220
+ mutex_unlock (& blkcg_pol_register_mutex );
1211
1221
return ret ;
1212
1222
}
1213
1223
EXPORT_SYMBOL_GPL (blkcg_policy_register );
@@ -1220,7 +1230,9 @@ EXPORT_SYMBOL_GPL(blkcg_policy_register);
1220
1230
*/
1221
1231
void blkcg_policy_unregister (struct blkcg_policy * pol )
1222
1232
{
1223
- mutex_lock (& blkcg_pol_mutex );
1233
+ struct blkcg * blkcg ;
1234
+
1235
+ mutex_lock (& blkcg_pol_register_mutex );
1224
1236
1225
1237
if (WARN_ON (blkcg_policy [pol -> plid ] != pol ))
1226
1238
goto out_unlock ;
@@ -1229,9 +1241,19 @@ void blkcg_policy_unregister(struct blkcg_policy *pol)
1229
1241
if (pol -> cftypes )
1230
1242
cgroup_rm_cftypes (pol -> cftypes );
1231
1243
1232
- /* unregister and update blkgs */
1244
+ /* remove cpds and unregister */
1245
+ mutex_lock (& blkcg_pol_mutex );
1246
+
1247
+ if (pol -> cpd_size ) {
1248
+ list_for_each_entry (blkcg , & all_blkcgs , all_blkcgs_node ) {
1249
+ kfree (blkcg -> pd [pol -> plid ]);
1250
+ blkcg -> pd [pol -> plid ] = NULL ;
1251
+ }
1252
+ }
1233
1253
blkcg_policy [pol -> plid ] = NULL ;
1234
- out_unlock :
1254
+
1235
1255
mutex_unlock (& blkcg_pol_mutex );
1256
+ out_unlock :
1257
+ mutex_unlock (& blkcg_pol_register_mutex );
1236
1258
}
1237
1259
EXPORT_SYMBOL_GPL (blkcg_policy_unregister );
0 commit comments