Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crush: eliminate CRUSH_MAX_SET result size limitation

This is only present to size the temporary scratch arrays that we put on
the stack. Let the caller allocate them as they wish and remove the
limitation.

Reflects ceph.git commit 1cfe140bf2dab99517589a82a916f4c75b9492d1.

Signed-off-by: Ilya Dryomov <ilya.dryomov@inktank.com>
Reviewed-by: Sage Weil <sage@inktank.com>

+21 -9
-1
include/linux/crush/crush.h
··· 21 21 22 22 23 23 #define CRUSH_MAX_DEPTH 10 /* max crush hierarchy depth */ 24 - #define CRUSH_MAX_SET 10 /* max size of a mapping result */ 25 24 26 25 27 26 /*
+2 -1
include/linux/crush/mapper.h
··· 14 14 extern int crush_do_rule(const struct crush_map *map, 15 15 int ruleno, 16 16 int x, int *result, int result_max, 17 - const __u32 *weights, int weight_max); 17 + const __u32 *weights, int weight_max, 18 + int *scratch); 18 19 19 20 #endif
+6 -4
net/ceph/crush/mapper.c
··· 478 478 * @result_max: maximum result size 479 479 * @weight: weight vector (for map leaves) 480 480 * @weight_max: size of weight vector 481 + * @scratch: scratch vector for private use; must be >= 3 * result_max 481 482 */ 482 483 int crush_do_rule(const struct crush_map *map, 483 484 int ruleno, int x, int *result, int result_max, 484 - const __u32 *weight, int weight_max) 485 + const __u32 *weight, int weight_max, 486 + int *scratch) 485 487 { 486 488 int result_len; 487 - int a[CRUSH_MAX_SET]; 488 - int b[CRUSH_MAX_SET]; 489 - int c[CRUSH_MAX_SET]; 489 + int *a = scratch; 490 + int *b = scratch + result_max; 491 + int *c = scratch + result_max*2; 490 492 int recurse_to_leaf; 491 493 int *w; 492 494 int wsize = 0;
+13 -3
net/ceph/osdmap.c
··· 1110 1110 } 1111 1111 EXPORT_SYMBOL(ceph_calc_ceph_pg); 1112 1112 1113 + static int crush_do_rule_ary(const struct crush_map *map, int ruleno, int x, 1114 + int *result, int result_max, 1115 + const __u32 *weight, int weight_max) 1116 + { 1117 + int scratch[result_max * 3]; 1118 + 1119 + return crush_do_rule(map, ruleno, x, result, result_max, 1120 + weight, weight_max, scratch); 1121 + } 1122 + 1113 1123 /* 1114 1124 * Calculate raw osd vector for the given pgid. Return pointer to osd 1115 1125 * array, or NULL on failure. ··· 1173 1163 pool->pgp_num_mask) + 1174 1164 (unsigned)pgid.pool; 1175 1165 } 1176 - r = crush_do_rule(osdmap->crush, ruleno, pps, osds, 1177 - min_t(int, pool->size, *num), 1178 - osdmap->osd_weight, osdmap->max_osd); 1166 + r = crush_do_rule_ary(osdmap->crush, ruleno, pps, 1167 + osds, min_t(int, pool->size, *num), 1168 + osdmap->osd_weight, osdmap->max_osd); 1179 1169 if (r < 0) { 1180 1170 pr_err("error %d from crush rule: pool %lld ruleset %d type %d" 1181 1171 " size %d\n", r, pgid.pool, pool->crush_ruleset,