aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeng Tao <bergwolf@gmail.com>2013-08-27 20:18:19 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-09-10 18:56:32 -0400
commitcbc3769ecd74b183d3ba5e11264cf484d8572a00 (patch)
treef7932c45a7369874b304a6a6ad0a53c38a2bcbce
parent488964666f71e46bc1d31ceb927c2b0124422c37 (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.c148
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
553struct ldlm_pool_ops ldlm_srv_pool_ops = { 549struct 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 */
608int ldlm_pool_shrink(struct ldlm_pool *pl, int nr, 605int 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
1019static struct ptlrpc_thread *ldlm_pools_thread; 1016static struct ptlrpc_thread *ldlm_pools_thread;
1020static struct shrinker *ldlm_pools_srv_shrinker;
1021static struct shrinker *ldlm_pools_cli_shrinker;
1022static struct completion ldlm_pools_comp; 1017static 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 */
1029static int ldlm_pools_shrink(ldlm_side_t client, int nr, 1023static 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
1076static 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
1125static 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
1125static int ldlm_pools_srv_shrink(SHRINKER_ARGS(sc, nr_to_scan, gfp_mask)) 1130static 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
1132static int ldlm_pools_cli_shrink(SHRINKER_ARGS(sc, nr_to_scan, gfp_mask)) 1136static 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
1141static 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
1139int ldlm_pools_recalc(ldlm_side_t client) 1147int 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
1394static 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
1400static 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
1386int ldlm_pools_init(void) 1406int 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
1403void ldlm_pools_fini(void) 1419void 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}
1415EXPORT_SYMBOL(ldlm_pools_fini); 1425EXPORT_SYMBOL(ldlm_pools_fini);