summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2015-06-12 06:21:07 -0400
committerIlya Dryomov <idryomov@gmail.com>2015-06-25 04:49:31 -0400
commitb459be739f97e2062b2ba77cfe8ea198dbd58904 (patch)
tree6765018f9d7842f0160b9cd858bd76e8a119491b
parent8f529795bace5d6263b134f4ff3adccfc0a0cce6 (diff)
crush: sync up with userspace
.. up to ceph.git commit 1db1abc8328d ("crush: eliminate ad hoc diff between kernel and userspace"). This fixes a bunch of recently pulled coding style issues and makes includes a bit cleaner. A patch "crush:Make the function crush_ln static" from Nicholas Krause <xerofoify@gmail.com> is folded in as crush_ln() has been made static in userspace as well. Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
-rw-r--r--include/linux/crush/crush.h40
-rw-r--r--include/linux/crush/hash.h6
-rw-r--r--include/linux/crush/mapper.h2
-rw-r--r--net/ceph/crush/crush.c13
-rw-r--r--net/ceph/crush/crush_ln_table.h32
-rw-r--r--net/ceph/crush/hash.c8
-rw-r--r--net/ceph/crush/mapper.c137
7 files changed, 160 insertions, 78 deletions
diff --git a/include/linux/crush/crush.h b/include/linux/crush/crush.h
index 48a1a7d100f1..48b49305716b 100644
--- a/include/linux/crush/crush.h
+++ b/include/linux/crush/crush.h
@@ -1,7 +1,11 @@
1#ifndef CEPH_CRUSH_CRUSH_H 1#ifndef CEPH_CRUSH_CRUSH_H
2#define CEPH_CRUSH_CRUSH_H 2#define CEPH_CRUSH_CRUSH_H
3 3
4#include <linux/types.h> 4#ifdef __KERNEL__
5# include <linux/types.h>
6#else
7# include "crush_compat.h"
8#endif
5 9
6/* 10/*
7 * CRUSH is a pseudo-random data distribution algorithm that 11 * CRUSH is a pseudo-random data distribution algorithm that
@@ -20,7 +24,11 @@
20#define CRUSH_MAGIC 0x00010000ul /* for detecting algorithm revisions */ 24#define CRUSH_MAGIC 0x00010000ul /* for detecting algorithm revisions */
21 25
22#define CRUSH_MAX_DEPTH 10 /* max crush hierarchy depth */ 26#define CRUSH_MAX_DEPTH 10 /* max crush hierarchy depth */
27#define CRUSH_MAX_RULESET (1<<8) /* max crush ruleset number */
28#define CRUSH_MAX_RULES CRUSH_MAX_RULESET /* should be the same as max rulesets */
23 29
30#define CRUSH_MAX_DEVICE_WEIGHT (100u * 0x10000u)
31#define CRUSH_MAX_BUCKET_WEIGHT (65535u * 0x10000u)
24 32
25#define CRUSH_ITEM_UNDEF 0x7ffffffe /* undefined result (internal use only) */ 33#define CRUSH_ITEM_UNDEF 0x7ffffffe /* undefined result (internal use only) */
26#define CRUSH_ITEM_NONE 0x7fffffff /* no result */ 34#define CRUSH_ITEM_NONE 0x7fffffff /* no result */
@@ -108,6 +116,15 @@ enum {
108}; 116};
109extern const char *crush_bucket_alg_name(int alg); 117extern const char *crush_bucket_alg_name(int alg);
110 118
119/*
120 * although tree was a legacy algorithm, it has been buggy, so
121 * exclude it.
122 */
123#define CRUSH_LEGACY_ALLOWED_BUCKET_ALGS ( \
124 (1 << CRUSH_BUCKET_UNIFORM) | \
125 (1 << CRUSH_BUCKET_LIST) | \
126 (1 << CRUSH_BUCKET_STRAW))
127
111struct crush_bucket { 128struct crush_bucket {
112 __s32 id; /* this'll be negative */ 129 __s32 id; /* this'll be negative */
113 __u16 type; /* non-zero; type=0 is reserved for devices */ 130 __u16 type; /* non-zero; type=0 is reserved for devices */
@@ -174,7 +191,7 @@ struct crush_map {
174 /* choose local attempts using a fallback permutation before 191 /* choose local attempts using a fallback permutation before
175 * re-descent */ 192 * re-descent */
176 __u32 choose_local_fallback_tries; 193 __u32 choose_local_fallback_tries;
177 /* choose attempts before giving up */ 194 /* choose attempts before giving up */
178 __u32 choose_total_tries; 195 __u32 choose_total_tries;
179 /* attempt chooseleaf inner descent once for firstn mode; on 196 /* attempt chooseleaf inner descent once for firstn mode; on
180 * reject retry outer descent. Note that this does *not* 197 * reject retry outer descent. Note that this does *not*
@@ -187,6 +204,25 @@ struct crush_map {
187 * that want to limit reshuffling, a value of 3 or 4 will make the 204 * that want to limit reshuffling, a value of 3 or 4 will make the
188 * mappings line up a bit better with previous mappings. */ 205 * mappings line up a bit better with previous mappings. */
189 __u8 chooseleaf_vary_r; 206 __u8 chooseleaf_vary_r;
207
208#ifndef __KERNEL__
209 /*
210 * version 0 (original) of straw_calc has various flaws. version 1
211 * fixes a few of them.
212 */
213 __u8 straw_calc_version;
214
215 /*
216 * allowed bucket algs is a bitmask, here the bit positions
217 * are CRUSH_BUCKET_*. note that these are *bits* and
218 * CRUSH_BUCKET_* values are not, so we need to or together (1
219 * << CRUSH_BUCKET_WHATEVER). The 0th bit is not used to
220 * minimize confusion (bucket type values start at 1).
221 */
222 __u32 allowed_bucket_algs;
223
224 __u32 *choose_tries;
225#endif
190}; 226};
191 227
192 228
diff --git a/include/linux/crush/hash.h b/include/linux/crush/hash.h
index 91e884230d5d..d1d90258242e 100644
--- a/include/linux/crush/hash.h
+++ b/include/linux/crush/hash.h
@@ -1,6 +1,12 @@
1#ifndef CEPH_CRUSH_HASH_H 1#ifndef CEPH_CRUSH_HASH_H
2#define CEPH_CRUSH_HASH_H 2#define CEPH_CRUSH_HASH_H
3 3
4#ifdef __KERNEL__
5# include <linux/types.h>
6#else
7# include "crush_compat.h"
8#endif
9
4#define CRUSH_HASH_RJENKINS1 0 10#define CRUSH_HASH_RJENKINS1 0
5 11
6#define CRUSH_HASH_DEFAULT CRUSH_HASH_RJENKINS1 12#define CRUSH_HASH_DEFAULT CRUSH_HASH_RJENKINS1
diff --git a/include/linux/crush/mapper.h b/include/linux/crush/mapper.h
index eab367446eea..5dfd5b1125d2 100644
--- a/include/linux/crush/mapper.h
+++ b/include/linux/crush/mapper.h
@@ -8,7 +8,7 @@
8 * LGPL2 8 * LGPL2
9 */ 9 */
10 10
11#include <linux/crush/crush.h> 11#include "crush.h"
12 12
13extern int crush_find_rule(const struct crush_map *map, int ruleset, int type, int size); 13extern int crush_find_rule(const struct crush_map *map, int ruleset, int type, int size);
14extern int crush_do_rule(const struct crush_map *map, 14extern int crush_do_rule(const struct crush_map *map,
diff --git a/net/ceph/crush/crush.c b/net/ceph/crush/crush.c
index 9d84ce4ea0df..80d7c3a97cb8 100644
--- a/net/ceph/crush/crush.c
+++ b/net/ceph/crush/crush.c
@@ -1,15 +1,11 @@
1
2#ifdef __KERNEL__ 1#ifdef __KERNEL__
3# include <linux/slab.h> 2# include <linux/slab.h>
3# include <linux/crush/crush.h>
4#else 4#else
5# include <stdlib.h> 5# include "crush_compat.h"
6# include <assert.h> 6# include "crush.h"
7# define kfree(x) do { if (x) free(x); } while (0)
8# define BUG_ON(x) assert(!(x))
9#endif 7#endif
10 8
11#include <linux/crush/crush.h>
12
13const char *crush_bucket_alg_name(int alg) 9const char *crush_bucket_alg_name(int alg)
14{ 10{
15 switch (alg) { 11 switch (alg) {
@@ -134,6 +130,9 @@ void crush_destroy(struct crush_map *map)
134 kfree(map->rules); 130 kfree(map->rules);
135 } 131 }
136 132
133#ifndef __KERNEL__
134 kfree(map->choose_tries);
135#endif
137 kfree(map); 136 kfree(map);
138} 137}
139 138
diff --git a/net/ceph/crush/crush_ln_table.h b/net/ceph/crush/crush_ln_table.h
index 6192c7fc958c..aae534c901a4 100644
--- a/net/ceph/crush/crush_ln_table.h
+++ b/net/ceph/crush/crush_ln_table.h
@@ -10,20 +10,20 @@
10 * 10 *
11 */ 11 */
12 12
13#if defined(__linux__)
14#include <linux/types.h>
15#elif defined(__FreeBSD__)
16#include <sys/types.h>
17#endif
18
19#ifndef CEPH_CRUSH_LN_H 13#ifndef CEPH_CRUSH_LN_H
20#define CEPH_CRUSH_LN_H 14#define CEPH_CRUSH_LN_H
21 15
16#ifdef __KERNEL__
17# include <linux/types.h>
18#else
19# include "crush_compat.h"
20#endif
22 21
23// RH_LH_tbl[2*k] = 2^48/(1.0+k/128.0) 22/*
24// RH_LH_tbl[2*k+1] = 2^48*log2(1.0+k/128.0) 23 * RH_LH_tbl[2*k] = 2^48/(1.0+k/128.0)
25 24 * RH_LH_tbl[2*k+1] = 2^48*log2(1.0+k/128.0)
26static int64_t __RH_LH_tbl[128*2+2] = { 25 */
26static __s64 __RH_LH_tbl[128*2+2] = {
27 0x0001000000000000ll, 0x0000000000000000ll, 0x0000fe03f80fe040ll, 0x000002dfca16dde1ll, 27 0x0001000000000000ll, 0x0000000000000000ll, 0x0000fe03f80fe040ll, 0x000002dfca16dde1ll,
28 0x0000fc0fc0fc0fc1ll, 0x000005b9e5a170b4ll, 0x0000fa232cf25214ll, 0x0000088e68ea899all, 28 0x0000fc0fc0fc0fc1ll, 0x000005b9e5a170b4ll, 0x0000fa232cf25214ll, 0x0000088e68ea899all,
29 0x0000f83e0f83e0f9ll, 0x00000b5d69bac77ell, 0x0000f6603d980f67ll, 0x00000e26fd5c8555ll, 29 0x0000f83e0f83e0f9ll, 0x00000b5d69bac77ell, 0x0000f6603d980f67ll, 0x00000e26fd5c8555ll,
@@ -89,11 +89,12 @@ static int64_t __RH_LH_tbl[128*2+2] = {
89 0x0000820820820821ll, 0x0000fa2f045e7832ll, 0x000081848da8faf1ll, 0x0000fba577877d7dll, 89 0x0000820820820821ll, 0x0000fa2f045e7832ll, 0x000081848da8faf1ll, 0x0000fba577877d7dll,
90 0x0000810204081021ll, 0x0000fd1a708bbe11ll, 0x0000808080808081ll, 0x0000fe8df263f957ll, 90 0x0000810204081021ll, 0x0000fd1a708bbe11ll, 0x0000808080808081ll, 0x0000fe8df263f957ll,
91 0x0000800000000000ll, 0x0000ffff00000000ll, 91 0x0000800000000000ll, 0x0000ffff00000000ll,
92 }; 92};
93
94 93
95 // LL_tbl[k] = 2^48*log2(1.0+k/2^15); 94/*
96static int64_t __LL_tbl[256] = { 95 * LL_tbl[k] = 2^48*log2(1.0+k/2^15)
96 */
97static __s64 __LL_tbl[256] = {
97 0x0000000000000000ull, 0x00000002e2a60a00ull, 0x000000070cb64ec5ull, 0x00000009ef50ce67ull, 98 0x0000000000000000ull, 0x00000002e2a60a00ull, 0x000000070cb64ec5ull, 0x00000009ef50ce67ull,
98 0x0000000cd1e588fdull, 0x0000000fb4747e9cull, 0x0000001296fdaf5eull, 0x0000001579811b58ull, 99 0x0000000cd1e588fdull, 0x0000000fb4747e9cull, 0x0000001296fdaf5eull, 0x0000001579811b58ull,
99 0x000000185bfec2a1ull, 0x0000001b3e76a552ull, 0x0000001e20e8c380ull, 0x0000002103551d43ull, 100 0x000000185bfec2a1ull, 0x0000001b3e76a552ull, 0x0000001e20e8c380ull, 0x0000002103551d43ull,
@@ -160,7 +161,4 @@ static int64_t __LL_tbl[256] = {
160 0x000002d4562d2ec6ull, 0x000002d73330209dull, 0x000002da102d63b0ull, 0x000002dced24f814ull, 161 0x000002d4562d2ec6ull, 0x000002d73330209dull, 0x000002da102d63b0ull, 0x000002dced24f814ull,
161}; 162};
162 163
163
164
165
166#endif 164#endif
diff --git a/net/ceph/crush/hash.c b/net/ceph/crush/hash.c
index 5bb63e37a8a1..ed123af49eba 100644
--- a/net/ceph/crush/hash.c
+++ b/net/ceph/crush/hash.c
@@ -1,6 +1,8 @@
1 1#ifdef __KERNEL__
2#include <linux/types.h> 2# include <linux/crush/hash.h>
3#include <linux/crush/hash.h> 3#else
4# include "hash.h"
5#endif
4 6
5/* 7/*
6 * Robert Jenkins' function for mixing 32-bit values 8 * Robert Jenkins' function for mixing 32-bit values
diff --git a/net/ceph/crush/mapper.c b/net/ceph/crush/mapper.c
index 7568cb59b9e5..393bfb22d5bb 100644
--- a/net/ceph/crush/mapper.c
+++ b/net/ceph/crush/mapper.c
@@ -1,27 +1,31 @@
1/*
2 * Ceph - scalable distributed file system
3 *
4 * Copyright (C) 2015 Intel Corporation All Rights Reserved
5 *
6 * This is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License version 2.1, as published by the Free Software
9 * Foundation. See file COPYING.
10 *
11 */
1 12
2#ifdef __KERNEL__ 13#ifdef __KERNEL__
3# include <linux/string.h> 14# include <linux/string.h>
4# include <linux/slab.h> 15# include <linux/slab.h>
5# include <linux/bug.h> 16# include <linux/bug.h>
6# include <linux/kernel.h> 17# include <linux/kernel.h>
7# ifndef dprintk 18# include <linux/crush/crush.h>
8# define dprintk(args...) 19# include <linux/crush/hash.h>
9# endif
10#else 20#else
11# include <string.h> 21# include "crush_compat.h"
12# include <stdio.h> 22# include "crush.h"
13# include <stdlib.h> 23# include "hash.h"
14# include <assert.h>
15# define BUG_ON(x) assert(!(x))
16# define dprintk(args...) /* printf(args) */
17# define kmalloc(x, f) malloc(x)
18# define kfree(x) free(x)
19#endif 24#endif
20
21#include <linux/crush/crush.h>
22#include <linux/crush/hash.h>
23#include "crush_ln_table.h" 25#include "crush_ln_table.h"
24 26
27#define dprintk(args...) /* printf(args) */
28
25/* 29/*
26 * Implement the core CRUSH mapping algorithm. 30 * Implement the core CRUSH mapping algorithm.
27 */ 31 */
@@ -139,7 +143,7 @@ static int bucket_list_choose(struct crush_bucket_list *bucket,
139 int i; 143 int i;
140 144
141 for (i = bucket->h.size-1; i >= 0; i--) { 145 for (i = bucket->h.size-1; i >= 0; i--) {
142 __u64 w = crush_hash32_4(bucket->h.hash,x, bucket->h.items[i], 146 __u64 w = crush_hash32_4(bucket->h.hash, x, bucket->h.items[i],
143 r, bucket->h.id); 147 r, bucket->h.id);
144 w &= 0xffff; 148 w &= 0xffff;
145 dprintk("list_choose i=%d x=%d r=%d item %d weight %x " 149 dprintk("list_choose i=%d x=%d r=%d item %d weight %x "
@@ -238,43 +242,46 @@ static int bucket_straw_choose(struct crush_bucket_straw *bucket,
238 return bucket->h.items[high]; 242 return bucket->h.items[high];
239} 243}
240 244
241// compute 2^44*log2(input+1) 245/* compute 2^44*log2(input+1) */
242uint64_t crush_ln(unsigned xin) 246static __u64 crush_ln(unsigned int xin)
243{ 247{
244 unsigned x=xin, x1; 248 unsigned int x = xin, x1;
245 int iexpon, index1, index2; 249 int iexpon, index1, index2;
246 uint64_t RH, LH, LL, xl64, result; 250 __u64 RH, LH, LL, xl64, result;
247 251
248 x++; 252 x++;
249 253
250 // normalize input 254 /* normalize input */
251 iexpon = 15; 255 iexpon = 15;
252 while(!(x&0x18000)) { x<<=1; iexpon--; } 256 while (!(x & 0x18000)) {
257 x <<= 1;
258 iexpon--;
259 }
253 260
254 index1 = (x>>8)<<1; 261 index1 = (x >> 8) << 1;
255 // RH ~ 2^56/index1 262 /* RH ~ 2^56/index1 */
256 RH = __RH_LH_tbl[index1 - 256]; 263 RH = __RH_LH_tbl[index1 - 256];
257 // LH ~ 2^48 * log2(index1/256) 264 /* LH ~ 2^48 * log2(index1/256) */
258 LH = __RH_LH_tbl[index1 + 1 - 256]; 265 LH = __RH_LH_tbl[index1 + 1 - 256];
259 266
260 // RH*x ~ 2^48 * (2^15 + xf), xf<2^8 267 /* RH*x ~ 2^48 * (2^15 + xf), xf<2^8 */
261 xl64 = (int64_t)x * RH; 268 xl64 = (__s64)x * RH;
262 xl64 >>= 48; 269 xl64 >>= 48;
263 x1 = xl64; 270 x1 = xl64;
264 271
265 result = iexpon; 272 result = iexpon;
266 result <<= (12 + 32); 273 result <<= (12 + 32);
267 274
268 index2 = x1 & 0xff; 275 index2 = x1 & 0xff;
269 // LL ~ 2^48*log2(1.0+index2/2^15) 276 /* LL ~ 2^48*log2(1.0+index2/2^15) */
270 LL = __LL_tbl[index2]; 277 LL = __LL_tbl[index2];
271 278
272 LH = LH + LL; 279 LH = LH + LL;
273 280
274 LH >>= (48-12 - 32); 281 LH >>= (48 - 12 - 32);
275 result += LH; 282 result += LH;
276 283
277 return result; 284 return result;
278} 285}
279 286
280 287
@@ -290,9 +297,9 @@ uint64_t crush_ln(unsigned xin)
290static int bucket_straw2_choose(struct crush_bucket_straw2 *bucket, 297static int bucket_straw2_choose(struct crush_bucket_straw2 *bucket,
291 int x, int r) 298 int x, int r)
292{ 299{
293 unsigned i, high = 0; 300 unsigned int i, high = 0;
294 unsigned u; 301 unsigned int u;
295 unsigned w; 302 unsigned int w;
296 __s64 ln, draw, high_draw = 0; 303 __s64 ln, draw, high_draw = 0;
297 304
298 for (i = 0; i < bucket->h.size; i++) { 305 for (i = 0; i < bucket->h.size; i++) {
@@ -567,6 +574,10 @@ reject:
567 out[outpos] = item; 574 out[outpos] = item;
568 outpos++; 575 outpos++;
569 count--; 576 count--;
577#ifndef __KERNEL__
578 if (map->choose_tries && ftotal <= map->choose_total_tries)
579 map->choose_tries[ftotal]++;
580#endif
570 } 581 }
571 582
572 dprintk("CHOOSE returns %d\n", outpos); 583 dprintk("CHOOSE returns %d\n", outpos);
@@ -610,6 +621,20 @@ static void crush_choose_indep(const struct crush_map *map,
610 } 621 }
611 622
612 for (ftotal = 0; left > 0 && ftotal < tries; ftotal++) { 623 for (ftotal = 0; left > 0 && ftotal < tries; ftotal++) {
624#ifdef DEBUG_INDEP
625 if (out2 && ftotal) {
626 dprintk("%u %d a: ", ftotal, left);
627 for (rep = outpos; rep < endpos; rep++) {
628 dprintk(" %d", out[rep]);
629 }
630 dprintk("\n");
631 dprintk("%u %d b: ", ftotal, left);
632 for (rep = outpos; rep < endpos; rep++) {
633 dprintk(" %d", out2[rep]);
634 }
635 dprintk("\n");
636 }
637#endif
613 for (rep = outpos; rep < endpos; rep++) { 638 for (rep = outpos; rep < endpos; rep++) {
614 if (out[rep] != CRUSH_ITEM_UNDEF) 639 if (out[rep] != CRUSH_ITEM_UNDEF)
615 continue; 640 continue;
@@ -726,6 +751,24 @@ static void crush_choose_indep(const struct crush_map *map,
726 out2[rep] = CRUSH_ITEM_NONE; 751 out2[rep] = CRUSH_ITEM_NONE;
727 } 752 }
728 } 753 }
754#ifndef __KERNEL__
755 if (map->choose_tries && ftotal <= map->choose_total_tries)
756 map->choose_tries[ftotal]++;
757#endif
758#ifdef DEBUG_INDEP
759 if (out2) {
760 dprintk("%u %d a: ", ftotal, left);
761 for (rep = outpos; rep < endpos; rep++) {
762 dprintk(" %d", out[rep]);
763 }
764 dprintk("\n");
765 dprintk("%u %d b: ", ftotal, left);
766 for (rep = outpos; rep < endpos; rep++) {
767 dprintk(" %d", out2[rep]);
768 }
769 dprintk("\n");
770 }
771#endif
729} 772}
730 773
731/** 774/**
@@ -884,7 +927,7 @@ int crush_do_rule(const struct crush_map *map,
884 0); 927 0);
885 } else { 928 } else {
886 out_size = ((numrep < (result_max-osize)) ? 929 out_size = ((numrep < (result_max-osize)) ?
887 numrep : (result_max-osize)); 930 numrep : (result_max-osize));
888 crush_choose_indep( 931 crush_choose_indep(
889 map, 932 map,
890 map->buckets[-1-w[i]], 933 map->buckets[-1-w[i]],
@@ -930,5 +973,3 @@ int crush_do_rule(const struct crush_map *map,
930 } 973 }
931 return result_len; 974 return result_len;
932} 975}
933
934