diff options
author | Peng Tao <bergwolf@gmail.com> | 2013-08-27 20:18:19 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-09-10 18:56:32 -0400 |
commit | cbc3769ecd74b183d3ba5e11264cf484d8572a00 (patch) | |
tree | f7932c45a7369874b304a6a6ad0a53c38a2bcbce | |
parent | 488964666f71e46bc1d31ceb927c2b0124422c37 (diff) |
staging/lustre/ldlm: convert to shrinkers to count/scan API
convert ldlm shrinker to new count/scan API.
Signed-off-by: Peng Tao <tao.peng@emc.com>
Signed-off-by: Andreas Dilger <andreas.dilger@intel.com>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | drivers/staging/lustre/lustre/ldlm/ldlm_pool.c | 148 |
1 files changed, 79 insertions, 69 deletions
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c index 454027d68d54..0025ee6356da 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c | |||
@@ -521,7 +521,7 @@ static int ldlm_cli_pool_shrink(struct ldlm_pool *pl, | |||
521 | int nr, unsigned int gfp_mask) | 521 | int nr, unsigned int gfp_mask) |
522 | { | 522 | { |
523 | struct ldlm_namespace *ns; | 523 | struct ldlm_namespace *ns; |
524 | int canceled = 0, unused; | 524 | int unused; |
525 | 525 | ||
526 | ns = ldlm_pl2ns(pl); | 526 | ns = ldlm_pl2ns(pl); |
527 | 527 | ||
@@ -540,14 +540,10 @@ static int ldlm_cli_pool_shrink(struct ldlm_pool *pl, | |||
540 | unused = ns->ns_nr_unused; | 540 | unused = ns->ns_nr_unused; |
541 | spin_unlock(&ns->ns_lock); | 541 | spin_unlock(&ns->ns_lock); |
542 | 542 | ||
543 | if (nr) { | 543 | if (nr == 0) |
544 | canceled = ldlm_cancel_lru(ns, nr, LCF_ASYNC, | 544 | return (unused / 100) * sysctl_vfs_cache_pressure; |
545 | LDLM_CANCEL_SHRINK); | 545 | else |
546 | } | 546 | return ldlm_cancel_lru(ns, nr, LCF_ASYNC, LDLM_CANCEL_SHRINK); |
547 | /* | ||
548 | * Return the number of potentially reclaimable locks. | ||
549 | */ | ||
550 | return ((unused - canceled) / 100) * sysctl_vfs_cache_pressure; | ||
551 | } | 547 | } |
552 | 548 | ||
553 | struct ldlm_pool_ops ldlm_srv_pool_ops = { | 549 | struct ldlm_pool_ops ldlm_srv_pool_ops = { |
@@ -601,9 +597,10 @@ int ldlm_pool_recalc(struct ldlm_pool *pl) | |||
601 | return recalc_interval_sec; | 597 | return recalc_interval_sec; |
602 | } | 598 | } |
603 | 599 | ||
604 | /** | 600 | /* |
605 | * Pool shrink wrapper. Will call either client or server pool recalc callback | 601 | * Pool shrink wrapper. Will call either client or server pool recalc callback |
606 | * depending what pool \a pl is used. | 602 | * depending what pool pl is used. When nr == 0, just return the number of |
603 | * freeable locks. Otherwise, return the number of canceled locks. | ||
607 | */ | 604 | */ |
608 | int ldlm_pool_shrink(struct ldlm_pool *pl, int nr, | 605 | int ldlm_pool_shrink(struct ldlm_pool *pl, int nr, |
609 | unsigned int gfp_mask) | 606 | unsigned int gfp_mask) |
@@ -1017,29 +1014,24 @@ static int ldlm_pool_granted(struct ldlm_pool *pl) | |||
1017 | } | 1014 | } |
1018 | 1015 | ||
1019 | static struct ptlrpc_thread *ldlm_pools_thread; | 1016 | static struct ptlrpc_thread *ldlm_pools_thread; |
1020 | static struct shrinker *ldlm_pools_srv_shrinker; | ||
1021 | static struct shrinker *ldlm_pools_cli_shrinker; | ||
1022 | static struct completion ldlm_pools_comp; | 1017 | static struct completion ldlm_pools_comp; |
1023 | 1018 | ||
1024 | /* | 1019 | /* |
1025 | * Cancel \a nr locks from all namespaces (if possible). Returns number of | 1020 | * count locks from all namespaces (if possible). Returns number of |
1026 | * cached locks after shrink is finished. All namespaces are asked to | 1021 | * cached locks. |
1027 | * cancel approximately equal amount of locks to keep balancing. | ||
1028 | */ | 1022 | */ |
1029 | static int ldlm_pools_shrink(ldlm_side_t client, int nr, | 1023 | static unsigned long ldlm_pools_count(ldlm_side_t client, unsigned int gfp_mask) |
1030 | unsigned int gfp_mask) | ||
1031 | { | 1024 | { |
1032 | int total = 0, cached = 0, nr_ns; | 1025 | int total = 0, nr_ns; |
1033 | struct ldlm_namespace *ns; | 1026 | struct ldlm_namespace *ns; |
1034 | struct ldlm_namespace *ns_old = NULL; /* loop detection */ | 1027 | struct ldlm_namespace *ns_old = NULL; /* loop detection */ |
1035 | void *cookie; | 1028 | void *cookie; |
1036 | 1029 | ||
1037 | if (client == LDLM_NAMESPACE_CLIENT && nr != 0 && | 1030 | if (client == LDLM_NAMESPACE_CLIENT && !(gfp_mask & __GFP_FS)) |
1038 | !(gfp_mask & __GFP_FS)) | 1031 | return 0; |
1039 | return -1; | ||
1040 | 1032 | ||
1041 | CDEBUG(D_DLMTRACE, "Request to shrink %d %s locks from all pools\n", | 1033 | CDEBUG(D_DLMTRACE, "Request to count %s locks from all pools\n", |
1042 | nr, client == LDLM_NAMESPACE_CLIENT ? "client" : "server"); | 1034 | client == LDLM_NAMESPACE_CLIENT ? "client" : "server"); |
1043 | 1035 | ||
1044 | cookie = cl_env_reenter(); | 1036 | cookie = cl_env_reenter(); |
1045 | 1037 | ||
@@ -1047,8 +1039,7 @@ static int ldlm_pools_shrink(ldlm_side_t client, int nr, | |||
1047 | * Find out how many resources we may release. | 1039 | * Find out how many resources we may release. |
1048 | */ | 1040 | */ |
1049 | for (nr_ns = ldlm_namespace_nr_read(client); | 1041 | for (nr_ns = ldlm_namespace_nr_read(client); |
1050 | nr_ns > 0; nr_ns--) | 1042 | nr_ns > 0; nr_ns--) { |
1051 | { | ||
1052 | mutex_lock(ldlm_namespace_lock(client)); | 1043 | mutex_lock(ldlm_namespace_lock(client)); |
1053 | if (list_empty(ldlm_namespace_list(client))) { | 1044 | if (list_empty(ldlm_namespace_list(client))) { |
1054 | mutex_unlock(ldlm_namespace_lock(client)); | 1045 | mutex_unlock(ldlm_namespace_lock(client)); |
@@ -1078,17 +1069,27 @@ static int ldlm_pools_shrink(ldlm_side_t client, int nr, | |||
1078 | ldlm_namespace_put(ns); | 1069 | ldlm_namespace_put(ns); |
1079 | } | 1070 | } |
1080 | 1071 | ||
1081 | if (nr == 0 || total == 0) { | 1072 | cl_env_reexit(cookie); |
1082 | cl_env_reexit(cookie); | 1073 | return total; |
1083 | return total; | 1074 | } |
1084 | } | 1075 | |
1076 | static unsigned long ldlm_pools_scan(ldlm_side_t client, int nr, unsigned int gfp_mask) | ||
1077 | { | ||
1078 | unsigned long freed = 0; | ||
1079 | int tmp, nr_ns; | ||
1080 | struct ldlm_namespace *ns; | ||
1081 | void *cookie; | ||
1082 | |||
1083 | if (client == LDLM_NAMESPACE_CLIENT && !(gfp_mask & __GFP_FS)) | ||
1084 | return -1; | ||
1085 | |||
1086 | cookie = cl_env_reenter(); | ||
1085 | 1087 | ||
1086 | /* | 1088 | /* |
1087 | * Shrink at least ldlm_namespace_nr(client) namespaces. | 1089 | * Shrink at least ldlm_namespace_nr_read(client) namespaces. |
1088 | */ | 1090 | */ |
1089 | for (nr_ns = ldlm_namespace_nr_read(client) - nr_ns; | 1091 | for (tmp = nr_ns = ldlm_namespace_nr_read(client); |
1090 | nr_ns > 0; nr_ns--) | 1092 | tmp > 0; tmp--) { |
1091 | { | ||
1092 | int cancel, nr_locks; | 1093 | int cancel, nr_locks; |
1093 | 1094 | ||
1094 | /* | 1095 | /* |
@@ -1097,12 +1098,6 @@ static int ldlm_pools_shrink(ldlm_side_t client, int nr, | |||
1097 | mutex_lock(ldlm_namespace_lock(client)); | 1098 | mutex_lock(ldlm_namespace_lock(client)); |
1098 | if (list_empty(ldlm_namespace_list(client))) { | 1099 | if (list_empty(ldlm_namespace_list(client))) { |
1099 | mutex_unlock(ldlm_namespace_lock(client)); | 1100 | mutex_unlock(ldlm_namespace_lock(client)); |
1100 | /* | ||
1101 | * If list is empty, we can't return any @cached > 0, | ||
1102 | * that probably would cause needless shrinker | ||
1103 | * call. | ||
1104 | */ | ||
1105 | cached = 0; | ||
1106 | break; | 1101 | break; |
1107 | } | 1102 | } |
1108 | ns = ldlm_namespace_first_locked(client); | 1103 | ns = ldlm_namespace_first_locked(client); |
@@ -1111,29 +1106,42 @@ static int ldlm_pools_shrink(ldlm_side_t client, int nr, | |||
1111 | mutex_unlock(ldlm_namespace_lock(client)); | 1106 | mutex_unlock(ldlm_namespace_lock(client)); |
1112 | 1107 | ||
1113 | nr_locks = ldlm_pool_granted(&ns->ns_pool); | 1108 | nr_locks = ldlm_pool_granted(&ns->ns_pool); |
1114 | cancel = 1 + nr_locks * nr / total; | 1109 | /* |
1115 | ldlm_pool_shrink(&ns->ns_pool, cancel, gfp_mask); | 1110 | * We use to shrink propotionally but with new shrinker API, |
1116 | cached += ldlm_pool_granted(&ns->ns_pool); | 1111 | * we lost the total number of freeable locks. |
1112 | */ | ||
1113 | cancel = 1 + min_t(int, nr_locks, nr / nr_ns); | ||
1114 | freed += ldlm_pool_shrink(&ns->ns_pool, cancel, gfp_mask); | ||
1117 | ldlm_namespace_put(ns); | 1115 | ldlm_namespace_put(ns); |
1118 | } | 1116 | } |
1119 | cl_env_reexit(cookie); | 1117 | cl_env_reexit(cookie); |
1120 | /* we only decrease the SLV in server pools shrinker, return -1 to | 1118 | /* |
1121 | * kernel to avoid needless loop. LU-1128 */ | 1119 | * we only decrease the SLV in server pools shrinker, return |
1122 | return (client == LDLM_NAMESPACE_SERVER) ? -1 : cached; | 1120 | * SHRINK_STOP to kernel to avoid needless loop. LU-1128 |
1121 | */ | ||
1122 | return (client == LDLM_NAMESPACE_SERVER) ? SHRINK_STOP : freed; | ||
1123 | } | ||
1124 | |||
1125 | static unsigned long ldlm_pools_srv_count(struct shrinker *s, struct shrink_control *sc) | ||
1126 | { | ||
1127 | return ldlm_pools_count(LDLM_NAMESPACE_SERVER, sc->gfp_mask); | ||
1123 | } | 1128 | } |
1124 | 1129 | ||
1125 | static int ldlm_pools_srv_shrink(SHRINKER_ARGS(sc, nr_to_scan, gfp_mask)) | 1130 | static unsigned long ldlm_pools_srv_scan(struct shrinker *s, struct shrink_control *sc) |
1126 | { | 1131 | { |
1127 | return ldlm_pools_shrink(LDLM_NAMESPACE_SERVER, | 1132 | return ldlm_pools_scan(LDLM_NAMESPACE_SERVER, sc->nr_to_scan, |
1128 | shrink_param(sc, nr_to_scan), | 1133 | sc->gfp_mask); |
1129 | shrink_param(sc, gfp_mask)); | ||
1130 | } | 1134 | } |
1131 | 1135 | ||
1132 | static int ldlm_pools_cli_shrink(SHRINKER_ARGS(sc, nr_to_scan, gfp_mask)) | 1136 | static unsigned long ldlm_pools_cli_count(struct shrinker *s, struct shrink_control *sc) |
1133 | { | 1137 | { |
1134 | return ldlm_pools_shrink(LDLM_NAMESPACE_CLIENT, | 1138 | return ldlm_pools_count(LDLM_NAMESPACE_CLIENT, sc->gfp_mask); |
1135 | shrink_param(sc, nr_to_scan), | 1139 | } |
1136 | shrink_param(sc, gfp_mask)); | 1140 | |
1141 | static unsigned long ldlm_pools_cli_scan(struct shrinker *s, struct shrink_control *sc) | ||
1142 | { | ||
1143 | return ldlm_pools_scan(LDLM_NAMESPACE_CLIENT, sc->nr_to_scan, | ||
1144 | sc->gfp_mask); | ||
1137 | } | 1145 | } |
1138 | 1146 | ||
1139 | int ldlm_pools_recalc(ldlm_side_t client) | 1147 | int ldlm_pools_recalc(ldlm_side_t client) |
@@ -1216,7 +1224,7 @@ int ldlm_pools_recalc(ldlm_side_t client) | |||
1216 | } | 1224 | } |
1217 | 1225 | ||
1218 | /* | 1226 | /* |
1219 | * Recalc at least ldlm_namespace_nr(client) namespaces. | 1227 | * Recalc at least ldlm_namespace_nr_read(client) namespaces. |
1220 | */ | 1228 | */ |
1221 | for (nr = ldlm_namespace_nr_read(client); nr > 0; nr--) { | 1229 | for (nr = ldlm_namespace_nr_read(client); nr > 0; nr--) { |
1222 | int skip; | 1230 | int skip; |
@@ -1383,18 +1391,26 @@ static void ldlm_pools_thread_stop(void) | |||
1383 | ldlm_pools_thread = NULL; | 1391 | ldlm_pools_thread = NULL; |
1384 | } | 1392 | } |
1385 | 1393 | ||
1394 | static struct shrinker ldlm_pools_srv_shrinker = { | ||
1395 | .count_objects = ldlm_pools_srv_count, | ||
1396 | .scan_objects = ldlm_pools_srv_scan, | ||
1397 | .seeks = DEFAULT_SEEKS, | ||
1398 | }; | ||
1399 | |||
1400 | static struct shrinker ldlm_pools_cli_shrinker = { | ||
1401 | .count_objects = ldlm_pools_cli_count, | ||
1402 | .scan_objects = ldlm_pools_cli_scan, | ||
1403 | .seeks = DEFAULT_SEEKS, | ||
1404 | }; | ||
1405 | |||
1386 | int ldlm_pools_init(void) | 1406 | int ldlm_pools_init(void) |
1387 | { | 1407 | { |
1388 | int rc; | 1408 | int rc; |
1389 | 1409 | ||
1390 | rc = ldlm_pools_thread_start(); | 1410 | rc = ldlm_pools_thread_start(); |
1391 | if (rc == 0) { | 1411 | if (rc == 0) { |
1392 | ldlm_pools_srv_shrinker = | 1412 | register_shrinker(&ldlm_pools_srv_shrinker); |
1393 | set_shrinker(DEFAULT_SEEKS, | 1413 | register_shrinker(&ldlm_pools_cli_shrinker); |
1394 | ldlm_pools_srv_shrink); | ||
1395 | ldlm_pools_cli_shrinker = | ||
1396 | set_shrinker(DEFAULT_SEEKS, | ||
1397 | ldlm_pools_cli_shrink); | ||
1398 | } | 1414 | } |
1399 | return rc; | 1415 | return rc; |
1400 | } | 1416 | } |
@@ -1402,14 +1418,8 @@ EXPORT_SYMBOL(ldlm_pools_init); | |||
1402 | 1418 | ||
1403 | void ldlm_pools_fini(void) | 1419 | void ldlm_pools_fini(void) |
1404 | { | 1420 | { |
1405 | if (ldlm_pools_srv_shrinker != NULL) { | 1421 | unregister_shrinker(&ldlm_pools_srv_shrinker); |
1406 | remove_shrinker(ldlm_pools_srv_shrinker); | 1422 | unregister_shrinker(&ldlm_pools_cli_shrinker); |
1407 | ldlm_pools_srv_shrinker = NULL; | ||
1408 | } | ||
1409 | if (ldlm_pools_cli_shrinker != NULL) { | ||
1410 | remove_shrinker(ldlm_pools_cli_shrinker); | ||
1411 | ldlm_pools_cli_shrinker = NULL; | ||
1412 | } | ||
1413 | ldlm_pools_thread_stop(); | 1423 | ldlm_pools_thread_stop(); |
1414 | } | 1424 | } |
1415 | EXPORT_SYMBOL(ldlm_pools_fini); | 1425 | EXPORT_SYMBOL(ldlm_pools_fini); |