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

crush: merge working data and scratch

Much like Arlo Guthrie, I decided that one big pile is better than two
little piles.

Reflects ceph.git commit 95c2df6c7e0b22d2ea9d91db500cf8b9441c73ba.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>

+29 -19
+1 -2
include/linux/ceph/osdmap.h
··· 173 173 * the list of osds that store+replicate them. */ 174 174 struct crush_map *crush; 175 175 176 - struct mutex crush_scratch_mutex; 177 - int crush_scratch_ary[CEPH_PG_MAX_SIZE * 3]; 176 + struct mutex crush_workspace_mutex; 178 177 void *crush_workspace; 179 178 }; 180 179
+13 -1
include/linux/crush/mapper.h
··· 15 15 int ruleno, 16 16 int x, int *result, int result_max, 17 17 const __u32 *weights, int weight_max, 18 - void *cwin, int *scratch); 18 + void *cwin); 19 + 20 + /* 21 + * Returns the exact amount of workspace that will need to be used 22 + * for a given combination of crush_map and result_max. The caller can 23 + * then allocate this much on its own, either on the stack, in a 24 + * per-thread long-lived buffer, or however it likes. 25 + */ 26 + static inline size_t crush_work_size(const struct crush_map *map, 27 + int result_max) 28 + { 29 + return map->working_size + result_max * 3 * sizeof(__u32); 30 + } 19 31 20 32 void crush_init_workspace(const struct crush_map *map, void *v); 21 33
+7 -10
net/ceph/crush/mapper.c
··· 855 855 * @result_max: maximum result size 856 856 * @weight: weight vector (for map leaves) 857 857 * @weight_max: size of weight vector 858 - * @cwin: pointer to at least map->working_size bytes of memory 859 - * @scratch: scratch vector for private use; must be >= 3 * result_max 858 + * @cwin: pointer to at least crush_work_size() bytes of memory 860 859 */ 861 860 int crush_do_rule(const struct crush_map *map, 862 861 int ruleno, int x, int *result, int result_max, 863 862 const __u32 *weight, int weight_max, 864 - void *cwin, int *scratch) 863 + void *cwin) 865 864 { 866 865 int result_len; 867 866 struct crush_work *cw = cwin; 868 - int *a = scratch; 869 - int *b = scratch + result_max; 870 - int *c = scratch + result_max*2; 867 + int *a = cwin + map->working_size; 868 + int *b = a + result_max; 869 + int *c = b + result_max; 870 + int *w = a; 871 + int *o = b; 871 872 int recurse_to_leaf; 872 - int *w; 873 873 int wsize = 0; 874 - int *o; 875 874 int osize; 876 875 int *tmp; 877 876 const struct crush_rule *rule; ··· 901 902 902 903 rule = map->rules[ruleno]; 903 904 result_len = 0; 904 - w = a; 905 - o = b; 906 905 907 906 for (step = 0; step < rule->len; step++) { 908 907 int firstn = 0;
+8 -6
net/ceph/osdmap.c
··· 743 743 map->pool_max = -1; 744 744 map->pg_temp = RB_ROOT; 745 745 map->primary_temp = RB_ROOT; 746 - mutex_init(&map->crush_scratch_mutex); 746 + mutex_init(&map->crush_workspace_mutex); 747 747 748 748 return map; 749 749 } ··· 836 836 static int osdmap_set_crush(struct ceph_osdmap *map, struct crush_map *crush) 837 837 { 838 838 void *workspace; 839 + size_t work_size; 839 840 840 841 if (IS_ERR(crush)) 841 842 return PTR_ERR(crush); 842 843 843 - workspace = kmalloc(crush->working_size, GFP_NOIO); 844 + work_size = crush_work_size(crush, CEPH_PG_MAX_SIZE); 845 + dout("%s work_size %zu bytes\n", __func__, work_size); 846 + workspace = kmalloc(work_size, GFP_NOIO); 844 847 if (!workspace) { 845 848 crush_destroy(crush); 846 849 return -ENOMEM; ··· 1977 1974 1978 1975 BUG_ON(result_max > CEPH_PG_MAX_SIZE); 1979 1976 1980 - mutex_lock(&map->crush_scratch_mutex); 1977 + mutex_lock(&map->crush_workspace_mutex); 1981 1978 r = crush_do_rule(map->crush, ruleno, x, result, result_max, 1982 - weight, weight_max, map->crush_workspace, 1983 - map->crush_scratch_ary); 1984 - mutex_unlock(&map->crush_scratch_mutex); 1979 + weight, weight_max, map->crush_workspace); 1980 + mutex_unlock(&map->crush_workspace_mutex); 1985 1981 1986 1982 return r; 1987 1983 }