From 55fb91d64071552ea1bc65ab4ea84d3c8b73ab4b Mon Sep 17 00:00:00 2001 From: Loic Dachary Date: Sat, 15 Apr 2017 18:31:42 +0200 Subject: [PATCH] crush: add per pool choose_args when calling do_rule If there is no crush_choose_arg_map for a given pool (the default) a NULL pointer is given instead and crush_do_rule behavior remains unchanged. Signed-off-by: Loic Dachary --- src/crush/CrushTester.cc | 2 +- src/crush/CrushWrapper.h | 42 ++++++++++++++++++- src/osd/OSDMap.cc | 2 +- src/test/crush/crush.cc | 24 +++++------ src/test/erasure-code/TestErasureCodeIsa.cc | 2 +- .../erasure-code/TestErasureCodeJerasure.cc | 2 +- src/test/erasure-code/TestErasureCodeLrc.cc | 2 +- 7 files changed, 57 insertions(+), 19 deletions(-) diff --git a/src/crush/CrushTester.cc b/src/crush/CrushTester.cc index 5cf68da2f46d5..c6822ad1a1833 100644 --- a/src/crush/CrushTester.cc +++ b/src/crush/CrushTester.cc @@ -645,7 +645,7 @@ int CrushTester::test() if (pool_id != -1) { real_x = crush_hash32_2(CRUSH_HASH_RJENKINS1, x, (uint32_t)pool_id); } - crush.do_rule(r, real_x, out, nr, weight); + crush.do_rule(r, real_x, out, nr, weight, 0); } else { if (output_mappings) err << "RNG"; // prepend RNG to placement output to denote simulation diff --git a/src/crush/CrushWrapper.h b/src/crush/CrushWrapper.h index 7a074b8738ac0..40c70793b9f36 100644 --- a/src/crush/CrushWrapper.h +++ b/src/crush/CrushWrapper.h @@ -58,6 +58,7 @@ public: std::map class_name; /* class id -> class name */ std::map class_rname; /* class name -> class id */ std::map > class_bucket; /* bucket[id][class] == id */ + std::map choose_args; private: struct crush_map *crush; @@ -87,6 +88,7 @@ public: ~CrushWrapper() { if (crush) crush_destroy(crush); + choose_args_clear(); } crush_map *get_crush_map() { return crush; } @@ -1099,6 +1101,7 @@ public: void finalize() { assert(crush); crush_finalize(crush); + choose_args_clear(); } int update_device_class(CephContext *cct, int id, const string& class_name, const string& name); @@ -1172,13 +1175,48 @@ public: return result; } + crush_choose_arg_map choose_args_get(uint64_t choose_args_index) const { + auto i = choose_args.find(choose_args_index); + if (i == choose_args.end()) { + crush_choose_arg_map arg_map; + arg_map.args = NULL; + arg_map.size = 0; + return arg_map; + } else { + return i->second; + } + } + + void destroy_choose_args(crush_choose_arg_map arg_map) { + for (__u32 i = 0; i < arg_map.size; i++) { + crush_choose_arg *arg = &arg_map.args[i]; + for (__u32 j = 0; j < arg->weight_set_size; j++) { + crush_weight_set *weight_set = &arg->weight_set[j]; + free(weight_set->weights); + } + if (arg->weight_set) + free(arg->weight_set); + if (arg->ids) + free(arg->ids); + } + free(arg_map.args); + } + + void choose_args_clear() { + for (auto w : choose_args) + destroy_choose_args(w.second); + choose_args.clear(); + } + void do_rule(int rule, int x, vector& out, int maxout, - const vector<__u32>& weight) const { + const vector<__u32>& weight, + uint64_t choose_args_index) const { int rawout[maxout]; char work[crush_work_size(crush, maxout)]; crush_init_workspace(crush, work); + crush_choose_arg_map arg_map = choose_args_get(choose_args_index); int numrep = crush_do_rule(crush, rule, x, rawout, maxout, &weight[0], - weight.size(), work); + weight.size(), work, arg_map.args); if (numrep < 0) numrep = 0; out.resize(numrep); diff --git a/src/osd/OSDMap.cc b/src/osd/OSDMap.cc index c4e388f86cfba..673d44fb40bdf 100644 --- a/src/osd/OSDMap.cc +++ b/src/osd/OSDMap.cc @@ -1674,7 +1674,7 @@ int OSDMap::_pg_to_raw_osds( // what crush rule? int ruleno = crush->find_rule(pool.get_crush_ruleset(), pool.get_type(), size); if (ruleno >= 0) - crush->do_rule(ruleno, pps, *osds, size, osd_weight); + crush->do_rule(ruleno, pps, *osds, size, osd_weight, pg.pool()); _remove_nonexistent_osds(pool, *osds); diff --git a/src/test/crush/crush.cc b/src/test/crush/crush.cc index 024a7d45adb84..a66591f54330c 100644 --- a/src/test/crush/crush.cc +++ b/src/test/crush/crush.cc @@ -100,7 +100,7 @@ TEST(CRUSH, indep_toosmall) { for (int x = 0; x < 100; ++x) { vector out; - c->do_rule(0, x, out, 5, weight); + c->do_rule(0, x, out, 5, weight, 0); cout << x << " -> " << out << std::endl; int num_none = 0; for (unsigned i=0; i out; - c->do_rule(0, x, out, 5, weight); + c->do_rule(0, x, out, 5, weight, 0); cout << x << " -> " << out << std::endl; int num_none = 0; for (unsigned i=0; iset_choose_total_tries(100); for (int x = 0; x < 100; ++x) { vector out; - c->do_rule(0, x, out, 9, weight); + c->do_rule(0, x, out, 9, weight, 0); cout << x << " -> " << out << std::endl; int num_none = 0; for (unsigned i=0; iset_choose_total_tries(100); for (int x = 0; x < 100; ++x) { vector out; - c->do_rule(0, x, out, 7, weight); + c->do_rule(0, x, out, 7, weight, 0); cout << x << " -> " << out << std::endl; int num_none = 0; for (unsigned i=0; i prev; for (unsigned i=0; i out; - c->do_rule(0, x, out, 7, weight); + c->do_rule(0, x, out, 7, weight, 0); cout << "(" << i << "/" << weight.size() << " out) " << x << " -> " << out << std::endl; int num_none = 0; @@ -291,9 +291,9 @@ TEST(CRUSH, straw_zero) { vector reweight(n, 0x10000); for (int i=0; i<10000; ++i) { vector out0, out1; - c->do_rule(ruleset0, i, out0, 1, reweight); + c->do_rule(ruleset0, i, out0, 1, reweight, 0); ASSERT_EQ(1u, out0.size()); - c->do_rule(ruleset1, i, out1, 1, reweight); + c->do_rule(ruleset1, i, out1, 1, reweight, 0); ASSERT_EQ(1u, out1.size()); ASSERT_EQ(out0[0], out1[0]); //cout << i << "\t" << out0 << "\t" << out1 << std::endl; @@ -387,9 +387,9 @@ TEST(CRUSH, straw_same) { int max = 100000; for (int i=0; i out0, out1; - c->do_rule(ruleset0, i, out0, 1, reweight); + c->do_rule(ruleset0, i, out0, 1, reweight, 0); ASSERT_EQ(1u, out0.size()); - c->do_rule(ruleset1, i, out1, 1, reweight); + c->do_rule(ruleset1, i, out1, 1, reweight, 0); ASSERT_EQ(1u, out1.size()); sum0[out0[0]]++; sum1[out1[0]]++; @@ -455,7 +455,7 @@ double calc_straw2_stddev(int *weights, int n, bool verbose) int total = 1000000; for (int i=0; i out; - c->do_rule(ruleset0, i, out, 1, reweight); + c->do_rule(ruleset0, i, out, 1, reweight, 0); sum[out[0]]++; } @@ -597,10 +597,10 @@ TEST(CRUSH, straw2_reweight) { int total = 1000000; for (int i=0; i out0, out1; - c->do_rule(ruleset0, i, out0, 1, reweight); + c->do_rule(ruleset0, i, out0, 1, reweight, 0); ASSERT_EQ(1u, out0.size()); - c->do_rule(ruleset1, i, out1, 1, reweight); + c->do_rule(ruleset1, i, out1, 1, reweight, 0); ASSERT_EQ(1u, out1.size()); sum[out1[0]]++; diff --git a/src/test/erasure-code/TestErasureCodeIsa.cc b/src/test/erasure-code/TestErasureCodeIsa.cc index 57773adc09dd8..40295cf4a6419 100644 --- a/src/test/erasure-code/TestErasureCodeIsa.cc +++ b/src/test/erasure-code/TestErasureCodeIsa.cc @@ -924,7 +924,7 @@ TEST_F(IsaErasureCodeTest, create_ruleset) vector<__u32> weight(c->get_max_devices(), 0x10000); vector out; int x = 0; - c->do_rule(ruleset, x, out, isa.get_chunk_count(), weight); + c->do_rule(ruleset, x, out, isa.get_chunk_count(), weight, 0); ASSERT_EQ(out.size(), isa.get_chunk_count()); for (unsigned i=0; i weight(c->get_max_devices(), 0x10000); vector out; int x = 0; - c->do_rule(ruleset, x, out, jerasure.get_chunk_count(), weight); + c->do_rule(ruleset, x, out, jerasure.get_chunk_count(), weight, 0); ASSERT_EQ(out.size(), jerasure.get_chunk_count()); for (unsigned i=0; iget_rule_id(rule_name); vector out; unsigned int n = racks * hosts; - c->do_rule(rule, 1, out, n, weight); + c->do_rule(rule, 1, out, n, weight, 0); EXPECT_EQ(n, out.size()); // // check that the first five are in the same rack and the next five -- 2.39.5