···173173 * the list of osds that store+replicate them. */174174 struct crush_map *crush;175175176176- struct mutex crush_scratch_mutex;177177- int crush_scratch_ary[CEPH_PG_MAX_SIZE * 3];176176+ struct mutex crush_workspace_mutex;178177 void *crush_workspace;179178};180179
+13-1
include/linux/crush/mapper.h
···1515 int ruleno,1616 int x, int *result, int result_max,1717 const __u32 *weights, int weight_max,1818- void *cwin, int *scratch);1818+ void *cwin);1919+2020+/*2121+ * Returns the exact amount of workspace that will need to be used2222+ * for a given combination of crush_map and result_max. The caller can2323+ * then allocate this much on its own, either on the stack, in a2424+ * per-thread long-lived buffer, or however it likes.2525+ */2626+static inline size_t crush_work_size(const struct crush_map *map,2727+ int result_max)2828+{2929+ return map->working_size + result_max * 3 * sizeof(__u32);3030+}19312032void crush_init_workspace(const struct crush_map *map, void *v);2133
+7-10
net/ceph/crush/mapper.c
···855855 * @result_max: maximum result size856856 * @weight: weight vector (for map leaves)857857 * @weight_max: size of weight vector858858- * @cwin: pointer to at least map->working_size bytes of memory859859- * @scratch: scratch vector for private use; must be >= 3 * result_max858858+ * @cwin: pointer to at least crush_work_size() bytes of memory860859 */861860int crush_do_rule(const struct crush_map *map,862861 int ruleno, int x, int *result, int result_max,863862 const __u32 *weight, int weight_max,864864- void *cwin, int *scratch)863863+ void *cwin)865864{866865 int result_len;867866 struct crush_work *cw = cwin;868868- int *a = scratch;869869- int *b = scratch + result_max;870870- int *c = scratch + result_max*2;867867+ int *a = cwin + map->working_size;868868+ int *b = a + result_max;869869+ int *c = b + result_max;870870+ int *w = a;871871+ int *o = b;871872 int recurse_to_leaf;872872- int *w;873873 int wsize = 0;874874- int *o;875874 int osize;876875 int *tmp;877876 const struct crush_rule *rule;···901902902903 rule = map->rules[ruleno];903904 result_len = 0;904904- w = a;905905- o = b;906905907906 for (step = 0; step < rule->len; step++) {908907 int firstn = 0;