util.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * random utility code, for bcache but in theory not specific to bcache
  4. *
  5. * Copyright 2010, 2011 Kent Overstreet <kent.overstreet@gmail.com>
  6. * Copyright 2012 Google, Inc.
  7. */
  8. #include <linux/bio.h>
  9. #include <linux/blkdev.h>
  10. #include <linux/console.h>
  11. #include <linux/ctype.h>
  12. #include <linux/debugfs.h>
  13. #include <linux/freezer.h>
  14. #include <linux/kthread.h>
  15. #include <linux/log2.h>
  16. #include <linux/math64.h>
  17. #include <linux/percpu.h>
  18. #include <linux/preempt.h>
  19. #include <linux/random.h>
  20. #include <linux/seq_file.h>
  21. #include <linux/string.h>
  22. #include <linux/types.h>
  23. #include <linux/sched/clock.h>
  24. #include "eytzinger.h"
  25. #include "mean_and_variance.h"
  26. #include "util.h"
  27. static const char si_units[] = "?kMGTPEZY";
  28. /* string_get_size units: */
  29. static const char *const units_2[] = {
  30. "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"
  31. };
  32. static const char *const units_10[] = {
  33. "B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"
  34. };
  35. static int parse_u64(const char *cp, u64 *res)
  36. {
  37. const char *start = cp;
  38. u64 v = 0;
  39. if (!isdigit(*cp))
  40. return -EINVAL;
  41. do {
  42. if (v > U64_MAX / 10)
  43. return -ERANGE;
  44. v *= 10;
  45. if (v > U64_MAX - (*cp - '0'))
  46. return -ERANGE;
  47. v += *cp - '0';
  48. cp++;
  49. } while (isdigit(*cp));
  50. *res = v;
  51. return cp - start;
  52. }
  53. static int bch2_pow(u64 n, u64 p, u64 *res)
  54. {
  55. *res = 1;
  56. while (p--) {
  57. if (*res > div64_u64(U64_MAX, n))
  58. return -ERANGE;
  59. *res *= n;
  60. }
  61. return 0;
  62. }
  63. static int parse_unit_suffix(const char *cp, u64 *res)
  64. {
  65. const char *start = cp;
  66. u64 base = 1024;
  67. unsigned u;
  68. int ret;
  69. if (*cp == ' ')
  70. cp++;
  71. for (u = 1; u < strlen(si_units); u++)
  72. if (*cp == si_units[u]) {
  73. cp++;
  74. goto got_unit;
  75. }
  76. for (u = 0; u < ARRAY_SIZE(units_2); u++)
  77. if (!strncmp(cp, units_2[u], strlen(units_2[u]))) {
  78. cp += strlen(units_2[u]);
  79. goto got_unit;
  80. }
  81. for (u = 0; u < ARRAY_SIZE(units_10); u++)
  82. if (!strncmp(cp, units_10[u], strlen(units_10[u]))) {
  83. cp += strlen(units_10[u]);
  84. base = 1000;
  85. goto got_unit;
  86. }
  87. *res = 1;
  88. return 0;
  89. got_unit:
  90. ret = bch2_pow(base, u, res);
  91. if (ret)
  92. return ret;
  93. return cp - start;
  94. }
  95. #define parse_or_ret(cp, _f) \
  96. do { \
  97. int _ret = _f; \
  98. if (_ret < 0) \
  99. return _ret; \
  100. cp += _ret; \
  101. } while (0)
  102. static int __bch2_strtou64_h(const char *cp, u64 *res)
  103. {
  104. const char *start = cp;
  105. u64 v = 0, b, f_n = 0, f_d = 1;
  106. int ret;
  107. parse_or_ret(cp, parse_u64(cp, &v));
  108. if (*cp == '.') {
  109. cp++;
  110. ret = parse_u64(cp, &f_n);
  111. if (ret < 0)
  112. return ret;
  113. cp += ret;
  114. ret = bch2_pow(10, ret, &f_d);
  115. if (ret)
  116. return ret;
  117. }
  118. parse_or_ret(cp, parse_unit_suffix(cp, &b));
  119. if (v > div64_u64(U64_MAX, b))
  120. return -ERANGE;
  121. v *= b;
  122. if (f_n > div64_u64(U64_MAX, b))
  123. return -ERANGE;
  124. f_n = div64_u64(f_n * b, f_d);
  125. if (v + f_n < v)
  126. return -ERANGE;
  127. v += f_n;
  128. *res = v;
  129. return cp - start;
  130. }
  131. static int __bch2_strtoh(const char *cp, u64 *res,
  132. u64 t_max, bool t_signed)
  133. {
  134. bool positive = *cp != '-';
  135. u64 v = 0;
  136. if (*cp == '+' || *cp == '-')
  137. cp++;
  138. parse_or_ret(cp, __bch2_strtou64_h(cp, &v));
  139. if (*cp == '\n')
  140. cp++;
  141. if (*cp)
  142. return -EINVAL;
  143. if (positive) {
  144. if (v > t_max)
  145. return -ERANGE;
  146. } else {
  147. if (v && !t_signed)
  148. return -ERANGE;
  149. if (v > t_max + 1)
  150. return -ERANGE;
  151. v = -v;
  152. }
  153. *res = v;
  154. return 0;
  155. }
  156. #define STRTO_H(name, type) \
  157. int bch2_ ## name ## _h(const char *cp, type *res) \
  158. { \
  159. u64 v = 0; \
  160. int ret = __bch2_strtoh(cp, &v, ANYSINT_MAX(type), \
  161. ANYSINT_MAX(type) != ((type) ~0ULL)); \
  162. *res = v; \
  163. return ret; \
  164. }
  165. STRTO_H(strtoint, int)
  166. STRTO_H(strtouint, unsigned int)
  167. STRTO_H(strtoll, long long)
  168. STRTO_H(strtoull, unsigned long long)
  169. STRTO_H(strtou64, u64)
  170. u64 bch2_read_flag_list(const char *opt, const char * const list[])
  171. {
  172. u64 ret = 0;
  173. char *p, *s, *d = kstrdup(opt, GFP_KERNEL);
  174. if (!d)
  175. return -ENOMEM;
  176. s = strim(d);
  177. while ((p = strsep(&s, ",;"))) {
  178. int flag = match_string(list, -1, p);
  179. if (flag < 0) {
  180. ret = -1;
  181. break;
  182. }
  183. ret |= BIT_ULL(flag);
  184. }
  185. kfree(d);
  186. return ret;
  187. }
  188. bool bch2_is_zero(const void *_p, size_t n)
  189. {
  190. const char *p = _p;
  191. size_t i;
  192. for (i = 0; i < n; i++)
  193. if (p[i])
  194. return false;
  195. return true;
  196. }
  197. void bch2_prt_u64_base2_nbits(struct printbuf *out, u64 v, unsigned nr_bits)
  198. {
  199. while (nr_bits)
  200. prt_char(out, '0' + ((v >> --nr_bits) & 1));
  201. }
  202. void bch2_prt_u64_base2(struct printbuf *out, u64 v)
  203. {
  204. bch2_prt_u64_base2_nbits(out, v, fls64(v) ?: 1);
  205. }
  206. static void __bch2_print_string_as_lines(const char *prefix, const char *lines,
  207. bool nonblocking)
  208. {
  209. bool locked = false;
  210. const char *p;
  211. if (!lines) {
  212. printk("%s (null)\n", prefix);
  213. return;
  214. }
  215. if (!nonblocking) {
  216. console_lock();
  217. locked = true;
  218. } else {
  219. locked = console_trylock();
  220. }
  221. while (1) {
  222. p = strchrnul(lines, '\n');
  223. printk("%s%.*s\n", prefix, (int) (p - lines), lines);
  224. if (!*p)
  225. break;
  226. lines = p + 1;
  227. }
  228. if (locked)
  229. console_unlock();
  230. }
  231. void bch2_print_string_as_lines(const char *prefix, const char *lines)
  232. {
  233. return __bch2_print_string_as_lines(prefix, lines, false);
  234. }
  235. void bch2_print_string_as_lines_nonblocking(const char *prefix, const char *lines)
  236. {
  237. return __bch2_print_string_as_lines(prefix, lines, true);
  238. }
  239. int bch2_save_backtrace(bch_stacktrace *stack, struct task_struct *task, unsigned skipnr,
  240. gfp_t gfp)
  241. {
  242. #ifdef CONFIG_STACKTRACE
  243. unsigned nr_entries = 0;
  244. stack->nr = 0;
  245. int ret = darray_make_room_gfp(stack, 32, gfp);
  246. if (ret)
  247. return ret;
  248. if (!down_read_trylock(&task->signal->exec_update_lock))
  249. return -1;
  250. do {
  251. nr_entries = stack_trace_save_tsk(task, stack->data, stack->size, skipnr + 1);
  252. } while (nr_entries == stack->size &&
  253. !(ret = darray_make_room_gfp(stack, stack->size * 2, gfp)));
  254. stack->nr = nr_entries;
  255. up_read(&task->signal->exec_update_lock);
  256. return ret;
  257. #else
  258. return 0;
  259. #endif
  260. }
  261. void bch2_prt_backtrace(struct printbuf *out, bch_stacktrace *stack)
  262. {
  263. darray_for_each(*stack, i) {
  264. prt_printf(out, "[<0>] %pB", (void *) *i);
  265. prt_newline(out);
  266. }
  267. }
  268. int bch2_prt_task_backtrace(struct printbuf *out, struct task_struct *task, unsigned skipnr, gfp_t gfp)
  269. {
  270. bch_stacktrace stack = { 0 };
  271. int ret = bch2_save_backtrace(&stack, task, skipnr + 1, gfp);
  272. bch2_prt_backtrace(out, &stack);
  273. darray_exit(&stack);
  274. return ret;
  275. }
  276. #ifndef __KERNEL__
  277. #include <time.h>
  278. void bch2_prt_datetime(struct printbuf *out, time64_t sec)
  279. {
  280. time_t t = sec;
  281. char buf[64];
  282. ctime_r(&t, buf);
  283. strim(buf);
  284. prt_str(out, buf);
  285. }
  286. #else
  287. void bch2_prt_datetime(struct printbuf *out, time64_t sec)
  288. {
  289. char buf[64];
  290. snprintf(buf, sizeof(buf), "%ptT", &sec);
  291. prt_u64(out, sec);
  292. }
  293. #endif
  294. void bch2_pr_time_units(struct printbuf *out, u64 ns)
  295. {
  296. const struct time_unit *u = bch2_pick_time_units(ns);
  297. prt_printf(out, "%llu %s", div64_u64(ns, u->nsecs), u->name);
  298. }
  299. static void bch2_pr_time_units_aligned(struct printbuf *out, u64 ns)
  300. {
  301. const struct time_unit *u = bch2_pick_time_units(ns);
  302. prt_printf(out, "%llu \r%s", div64_u64(ns, u->nsecs), u->name);
  303. }
  304. static inline void pr_name_and_units(struct printbuf *out, const char *name, u64 ns)
  305. {
  306. prt_printf(out, "%s\t", name);
  307. bch2_pr_time_units_aligned(out, ns);
  308. prt_newline(out);
  309. }
  310. #define TABSTOP_SIZE 12
  311. void bch2_time_stats_to_text(struct printbuf *out, struct bch2_time_stats *stats)
  312. {
  313. struct quantiles *quantiles = time_stats_to_quantiles(stats);
  314. s64 f_mean = 0, d_mean = 0;
  315. u64 f_stddev = 0, d_stddev = 0;
  316. if (stats->buffer) {
  317. int cpu;
  318. spin_lock_irq(&stats->lock);
  319. for_each_possible_cpu(cpu)
  320. __bch2_time_stats_clear_buffer(stats, per_cpu_ptr(stats->buffer, cpu));
  321. spin_unlock_irq(&stats->lock);
  322. }
  323. /*
  324. * avoid divide by zero
  325. */
  326. if (stats->freq_stats.n) {
  327. f_mean = mean_and_variance_get_mean(stats->freq_stats);
  328. f_stddev = mean_and_variance_get_stddev(stats->freq_stats);
  329. d_mean = mean_and_variance_get_mean(stats->duration_stats);
  330. d_stddev = mean_and_variance_get_stddev(stats->duration_stats);
  331. }
  332. printbuf_tabstop_push(out, out->indent + TABSTOP_SIZE);
  333. prt_printf(out, "count:\t%llu\n", stats->duration_stats.n);
  334. printbuf_tabstop_pop(out);
  335. printbuf_tabstops_reset(out);
  336. printbuf_tabstop_push(out, out->indent + 20);
  337. printbuf_tabstop_push(out, TABSTOP_SIZE + 2);
  338. printbuf_tabstop_push(out, 0);
  339. printbuf_tabstop_push(out, TABSTOP_SIZE + 2);
  340. prt_printf(out, "\tsince mount\r\trecent\r\n");
  341. printbuf_tabstops_reset(out);
  342. printbuf_tabstop_push(out, out->indent + 20);
  343. printbuf_tabstop_push(out, TABSTOP_SIZE);
  344. printbuf_tabstop_push(out, 2);
  345. printbuf_tabstop_push(out, TABSTOP_SIZE);
  346. prt_printf(out, "duration of events\n");
  347. printbuf_indent_add(out, 2);
  348. pr_name_and_units(out, "min:", stats->min_duration);
  349. pr_name_and_units(out, "max:", stats->max_duration);
  350. pr_name_and_units(out, "total:", stats->total_duration);
  351. prt_printf(out, "mean:\t");
  352. bch2_pr_time_units_aligned(out, d_mean);
  353. prt_tab(out);
  354. bch2_pr_time_units_aligned(out, mean_and_variance_weighted_get_mean(stats->duration_stats_weighted, TIME_STATS_MV_WEIGHT));
  355. prt_newline(out);
  356. prt_printf(out, "stddev:\t");
  357. bch2_pr_time_units_aligned(out, d_stddev);
  358. prt_tab(out);
  359. bch2_pr_time_units_aligned(out, mean_and_variance_weighted_get_stddev(stats->duration_stats_weighted, TIME_STATS_MV_WEIGHT));
  360. printbuf_indent_sub(out, 2);
  361. prt_newline(out);
  362. prt_printf(out, "time between events\n");
  363. printbuf_indent_add(out, 2);
  364. pr_name_and_units(out, "min:", stats->min_freq);
  365. pr_name_and_units(out, "max:", stats->max_freq);
  366. prt_printf(out, "mean:\t");
  367. bch2_pr_time_units_aligned(out, f_mean);
  368. prt_tab(out);
  369. bch2_pr_time_units_aligned(out, mean_and_variance_weighted_get_mean(stats->freq_stats_weighted, TIME_STATS_MV_WEIGHT));
  370. prt_newline(out);
  371. prt_printf(out, "stddev:\t");
  372. bch2_pr_time_units_aligned(out, f_stddev);
  373. prt_tab(out);
  374. bch2_pr_time_units_aligned(out, mean_and_variance_weighted_get_stddev(stats->freq_stats_weighted, TIME_STATS_MV_WEIGHT));
  375. printbuf_indent_sub(out, 2);
  376. prt_newline(out);
  377. printbuf_tabstops_reset(out);
  378. if (quantiles) {
  379. int i = eytzinger0_first(NR_QUANTILES);
  380. const struct time_unit *u =
  381. bch2_pick_time_units(quantiles->entries[i].m);
  382. u64 last_q = 0;
  383. prt_printf(out, "quantiles (%s):\t", u->name);
  384. eytzinger0_for_each(i, NR_QUANTILES) {
  385. bool is_last = eytzinger0_next(i, NR_QUANTILES) == -1;
  386. u64 q = max(quantiles->entries[i].m, last_q);
  387. prt_printf(out, "%llu ", div64_u64(q, u->nsecs));
  388. if (is_last)
  389. prt_newline(out);
  390. last_q = q;
  391. }
  392. }
  393. }
  394. /* ratelimit: */
  395. /**
  396. * bch2_ratelimit_delay() - return how long to delay until the next time to do
  397. * some work
  398. * @d: the struct bch_ratelimit to update
  399. * Returns: the amount of time to delay by, in jiffies
  400. */
  401. u64 bch2_ratelimit_delay(struct bch_ratelimit *d)
  402. {
  403. u64 now = local_clock();
  404. return time_after64(d->next, now)
  405. ? nsecs_to_jiffies(d->next - now)
  406. : 0;
  407. }
  408. /**
  409. * bch2_ratelimit_increment() - increment @d by the amount of work done
  410. * @d: the struct bch_ratelimit to update
  411. * @done: the amount of work done, in arbitrary units
  412. */
  413. void bch2_ratelimit_increment(struct bch_ratelimit *d, u64 done)
  414. {
  415. u64 now = local_clock();
  416. d->next += div_u64(done * NSEC_PER_SEC, d->rate);
  417. if (time_before64(now + NSEC_PER_SEC, d->next))
  418. d->next = now + NSEC_PER_SEC;
  419. if (time_after64(now - NSEC_PER_SEC * 2, d->next))
  420. d->next = now - NSEC_PER_SEC * 2;
  421. }
  422. /* pd controller: */
  423. /*
  424. * Updates pd_controller. Attempts to scale inputed values to units per second.
  425. * @target: desired value
  426. * @actual: current value
  427. *
  428. * @sign: 1 or -1; 1 if increasing the rate makes actual go up, -1 if increasing
  429. * it makes actual go down.
  430. */
  431. void bch2_pd_controller_update(struct bch_pd_controller *pd,
  432. s64 target, s64 actual, int sign)
  433. {
  434. s64 proportional, derivative, change;
  435. unsigned long seconds_since_update = (jiffies - pd->last_update) / HZ;
  436. if (seconds_since_update == 0)
  437. return;
  438. pd->last_update = jiffies;
  439. proportional = actual - target;
  440. proportional *= seconds_since_update;
  441. proportional = div_s64(proportional, pd->p_term_inverse);
  442. derivative = actual - pd->last_actual;
  443. derivative = div_s64(derivative, seconds_since_update);
  444. derivative = ewma_add(pd->smoothed_derivative, derivative,
  445. (pd->d_term / seconds_since_update) ?: 1);
  446. derivative = derivative * pd->d_term;
  447. derivative = div_s64(derivative, pd->p_term_inverse);
  448. change = proportional + derivative;
  449. /* Don't increase rate if not keeping up */
  450. if (change > 0 &&
  451. pd->backpressure &&
  452. time_after64(local_clock(),
  453. pd->rate.next + NSEC_PER_MSEC))
  454. change = 0;
  455. change *= (sign * -1);
  456. pd->rate.rate = clamp_t(s64, (s64) pd->rate.rate + change,
  457. 1, UINT_MAX);
  458. pd->last_actual = actual;
  459. pd->last_derivative = derivative;
  460. pd->last_proportional = proportional;
  461. pd->last_change = change;
  462. pd->last_target = target;
  463. }
  464. void bch2_pd_controller_init(struct bch_pd_controller *pd)
  465. {
  466. pd->rate.rate = 1024;
  467. pd->last_update = jiffies;
  468. pd->p_term_inverse = 6000;
  469. pd->d_term = 30;
  470. pd->d_smooth = pd->d_term;
  471. pd->backpressure = 1;
  472. }
  473. void bch2_pd_controller_debug_to_text(struct printbuf *out, struct bch_pd_controller *pd)
  474. {
  475. if (!out->nr_tabstops)
  476. printbuf_tabstop_push(out, 20);
  477. prt_printf(out, "rate:\t");
  478. prt_human_readable_s64(out, pd->rate.rate);
  479. prt_newline(out);
  480. prt_printf(out, "target:\t");
  481. prt_human_readable_u64(out, pd->last_target);
  482. prt_newline(out);
  483. prt_printf(out, "actual:\t");
  484. prt_human_readable_u64(out, pd->last_actual);
  485. prt_newline(out);
  486. prt_printf(out, "proportional:\t");
  487. prt_human_readable_s64(out, pd->last_proportional);
  488. prt_newline(out);
  489. prt_printf(out, "derivative:\t");
  490. prt_human_readable_s64(out, pd->last_derivative);
  491. prt_newline(out);
  492. prt_printf(out, "change:\t");
  493. prt_human_readable_s64(out, pd->last_change);
  494. prt_newline(out);
  495. prt_printf(out, "next io:\t%llims\n", div64_s64(pd->rate.next - local_clock(), NSEC_PER_MSEC));
  496. }
  497. /* misc: */
  498. void bch2_bio_map(struct bio *bio, void *base, size_t size)
  499. {
  500. while (size) {
  501. struct page *page = is_vmalloc_addr(base)
  502. ? vmalloc_to_page(base)
  503. : virt_to_page(base);
  504. unsigned offset = offset_in_page(base);
  505. unsigned len = min_t(size_t, PAGE_SIZE - offset, size);
  506. BUG_ON(!bio_add_page(bio, page, len, offset));
  507. size -= len;
  508. base += len;
  509. }
  510. }
  511. int bch2_bio_alloc_pages(struct bio *bio, size_t size, gfp_t gfp_mask)
  512. {
  513. while (size) {
  514. struct page *page = alloc_pages(gfp_mask, 0);
  515. unsigned len = min_t(size_t, PAGE_SIZE, size);
  516. if (!page)
  517. return -ENOMEM;
  518. if (unlikely(!bio_add_page(bio, page, len, 0))) {
  519. __free_page(page);
  520. break;
  521. }
  522. size -= len;
  523. }
  524. return 0;
  525. }
  526. size_t bch2_rand_range(size_t max)
  527. {
  528. size_t rand;
  529. if (!max)
  530. return 0;
  531. do {
  532. rand = get_random_long();
  533. rand &= roundup_pow_of_two(max) - 1;
  534. } while (rand >= max);
  535. return rand;
  536. }
  537. void memcpy_to_bio(struct bio *dst, struct bvec_iter dst_iter, const void *src)
  538. {
  539. struct bio_vec bv;
  540. struct bvec_iter iter;
  541. __bio_for_each_segment(bv, dst, iter, dst_iter) {
  542. void *dstp = kmap_local_page(bv.bv_page);
  543. memcpy(dstp + bv.bv_offset, src, bv.bv_len);
  544. kunmap_local(dstp);
  545. src += bv.bv_len;
  546. }
  547. }
  548. void memcpy_from_bio(void *dst, struct bio *src, struct bvec_iter src_iter)
  549. {
  550. struct bio_vec bv;
  551. struct bvec_iter iter;
  552. __bio_for_each_segment(bv, src, iter, src_iter) {
  553. void *srcp = kmap_local_page(bv.bv_page);
  554. memcpy(dst, srcp + bv.bv_offset, bv.bv_len);
  555. kunmap_local(srcp);
  556. dst += bv.bv_len;
  557. }
  558. }
  559. #if 0
  560. void eytzinger1_test(void)
  561. {
  562. unsigned inorder, eytz, size;
  563. pr_info("1 based eytzinger test:");
  564. for (size = 2;
  565. size < 65536;
  566. size++) {
  567. unsigned extra = eytzinger1_extra(size);
  568. if (!(size % 4096))
  569. pr_info("tree size %u", size);
  570. BUG_ON(eytzinger1_prev(0, size) != eytzinger1_last(size));
  571. BUG_ON(eytzinger1_next(0, size) != eytzinger1_first(size));
  572. BUG_ON(eytzinger1_prev(eytzinger1_first(size), size) != 0);
  573. BUG_ON(eytzinger1_next(eytzinger1_last(size), size) != 0);
  574. inorder = 1;
  575. eytzinger1_for_each(eytz, size) {
  576. BUG_ON(__inorder_to_eytzinger1(inorder, size, extra) != eytz);
  577. BUG_ON(__eytzinger1_to_inorder(eytz, size, extra) != inorder);
  578. BUG_ON(eytz != eytzinger1_last(size) &&
  579. eytzinger1_prev(eytzinger1_next(eytz, size), size) != eytz);
  580. inorder++;
  581. }
  582. }
  583. }
  584. void eytzinger0_test(void)
  585. {
  586. unsigned inorder, eytz, size;
  587. pr_info("0 based eytzinger test:");
  588. for (size = 1;
  589. size < 65536;
  590. size++) {
  591. unsigned extra = eytzinger0_extra(size);
  592. if (!(size % 4096))
  593. pr_info("tree size %u", size);
  594. BUG_ON(eytzinger0_prev(-1, size) != eytzinger0_last(size));
  595. BUG_ON(eytzinger0_next(-1, size) != eytzinger0_first(size));
  596. BUG_ON(eytzinger0_prev(eytzinger0_first(size), size) != -1);
  597. BUG_ON(eytzinger0_next(eytzinger0_last(size), size) != -1);
  598. inorder = 0;
  599. eytzinger0_for_each(eytz, size) {
  600. BUG_ON(__inorder_to_eytzinger0(inorder, size, extra) != eytz);
  601. BUG_ON(__eytzinger0_to_inorder(eytz, size, extra) != inorder);
  602. BUG_ON(eytz != eytzinger0_last(size) &&
  603. eytzinger0_prev(eytzinger0_next(eytz, size), size) != eytz);
  604. inorder++;
  605. }
  606. }
  607. }
  608. static inline int cmp_u16(const void *_l, const void *_r, size_t size)
  609. {
  610. const u16 *l = _l, *r = _r;
  611. return (*l > *r) - (*r - *l);
  612. }
  613. static void eytzinger0_find_test_val(u16 *test_array, unsigned nr, u16 search)
  614. {
  615. int i, c1 = -1, c2 = -1;
  616. ssize_t r;
  617. r = eytzinger0_find_le(test_array, nr,
  618. sizeof(test_array[0]),
  619. cmp_u16, &search);
  620. if (r >= 0)
  621. c1 = test_array[r];
  622. for (i = 0; i < nr; i++)
  623. if (test_array[i] <= search && test_array[i] > c2)
  624. c2 = test_array[i];
  625. if (c1 != c2) {
  626. eytzinger0_for_each(i, nr)
  627. pr_info("[%3u] = %12u", i, test_array[i]);
  628. pr_info("find_le(%2u) -> [%2zi] = %2i should be %2i",
  629. i, r, c1, c2);
  630. }
  631. }
  632. void eytzinger0_find_test(void)
  633. {
  634. unsigned i, nr, allocated = 1 << 12;
  635. u16 *test_array = kmalloc_array(allocated, sizeof(test_array[0]), GFP_KERNEL);
  636. for (nr = 1; nr < allocated; nr++) {
  637. pr_info("testing %u elems", nr);
  638. get_random_bytes(test_array, nr * sizeof(test_array[0]));
  639. eytzinger0_sort(test_array, nr, sizeof(test_array[0]), cmp_u16, NULL);
  640. /* verify array is sorted correctly: */
  641. eytzinger0_for_each(i, nr)
  642. BUG_ON(i != eytzinger0_last(nr) &&
  643. test_array[i] > test_array[eytzinger0_next(i, nr)]);
  644. for (i = 0; i < U16_MAX; i += 1 << 12)
  645. eytzinger0_find_test_val(test_array, nr, i);
  646. for (i = 0; i < nr; i++) {
  647. eytzinger0_find_test_val(test_array, nr, test_array[i] - 1);
  648. eytzinger0_find_test_val(test_array, nr, test_array[i]);
  649. eytzinger0_find_test_val(test_array, nr, test_array[i] + 1);
  650. }
  651. }
  652. kfree(test_array);
  653. }
  654. #endif
  655. /*
  656. * Accumulate percpu counters onto one cpu's copy - only valid when access
  657. * against any percpu counter is guarded against
  658. */
  659. u64 *bch2_acc_percpu_u64s(u64 __percpu *p, unsigned nr)
  660. {
  661. u64 *ret;
  662. int cpu;
  663. /* access to pcpu vars has to be blocked by other locking */
  664. preempt_disable();
  665. ret = this_cpu_ptr(p);
  666. preempt_enable();
  667. for_each_possible_cpu(cpu) {
  668. u64 *i = per_cpu_ptr(p, cpu);
  669. if (i != ret) {
  670. acc_u64s(ret, i, nr);
  671. memset(i, 0, nr * sizeof(u64));
  672. }
  673. }
  674. return ret;
  675. }
  676. void bch2_darray_str_exit(darray_str *d)
  677. {
  678. darray_for_each(*d, i)
  679. kfree(*i);
  680. darray_exit(d);
  681. }
  682. int bch2_split_devs(const char *_dev_name, darray_str *ret)
  683. {
  684. darray_init(ret);
  685. char *dev_name, *s, *orig;
  686. dev_name = orig = kstrdup(_dev_name, GFP_KERNEL);
  687. if (!dev_name)
  688. return -ENOMEM;
  689. while ((s = strsep(&dev_name, ":"))) {
  690. char *p = kstrdup(s, GFP_KERNEL);
  691. if (!p)
  692. goto err;
  693. if (darray_push(ret, p)) {
  694. kfree(p);
  695. goto err;
  696. }
  697. }
  698. kfree(orig);
  699. return 0;
  700. err:
  701. bch2_darray_str_exit(ret);
  702. kfree(orig);
  703. return -ENOMEM;
  704. }