alloc.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945
  1. #include <unistd.h>
  2. #include <stdint.h>
  3. #include <string.h>
  4. #include <limits.h>
  5. #include <assert.h>
  6. #include <stdlib.h>
  7. #include "alloc.h"
  8. #include <ccan/build_assert/build_assert.h>
  9. #include <ccan/likely/likely.h>
  10. #include <ccan/short_types/short_types.h>
  11. #include "config.h"
  12. /*
  13. Inspired by (and parts taken from) Andrew Tridgell's alloc_mmap:
  14. http://samba.org/~tridge/junkcode/alloc_mmap/
  15. Copyright (C) Andrew Tridgell 2007
  16. This library is free software; you can redistribute it and/or
  17. modify it under the terms of the GNU Lesser General Public
  18. License as published by the Free Software Foundation; either
  19. version 2 of the License, or (at your option) any later version.
  20. This library is distributed in the hope that it will be useful,
  21. but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  23. Lesser General Public License for more details.
  24. You should have received a copy of the GNU Lesser General Public
  25. License along with this library; if not, write to the Free Software
  26. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  27. */
  28. #if 0 /* Until we have the tiny allocator working, go down to 1 MB */
  29. /* We divide the pool into this many large pages (nearest power of 2) */
  30. #define MAX_PAGES (1024UL)
  31. /* 32 small pages == 1 large page. */
  32. #define BITS_FROM_SMALL_TO_LARGE_PAGE 5
  33. #else
  34. #define MAX_PAGES (128UL)
  35. #define BITS_FROM_SMALL_TO_LARGE_PAGE 4
  36. #endif
  37. /* Smallest pool size for this scheme: 512-byte small pages. That's
  38. * 4/8% overhead for 32/64 bit. */
  39. #define MIN_USEFUL_SIZE (MAX_PAGES << (9 + BITS_FROM_SMALL_TO_LARGE_PAGE))
  40. /* Every 4 buckets, we jump up a power of 2. ...8 10 12 14 16 20 24 28 32... */
  41. #define INTER_BUCKET_SPACE 4
  42. /* FIXME: Figure this out properly. */
  43. #define MAX_SIZE (1 << 30)
  44. /* How few object to fit in a page before using a larger one? (8) */
  45. #define MAX_PAGE_OBJECT_ORDER 3
  46. #define BITS_PER_LONG (sizeof(long) * CHAR_BIT)
  47. struct bucket_state {
  48. unsigned long elements_per_page;
  49. unsigned long page_list;
  50. unsigned long full_list;
  51. };
  52. struct header {
  53. /* 1024 bit bitmap of which pages are large. */
  54. unsigned long pagesize[MAX_PAGES / BITS_PER_LONG];
  55. /* List of unused small/large pages. */
  56. unsigned long small_free_list;
  57. unsigned long large_free_list;
  58. /* This is less defined: we have two buckets for each power of 2 */
  59. struct bucket_state bs[1];
  60. };
  61. struct page_header {
  62. unsigned long next, prev;
  63. u32 elements_used;
  64. /* FIXME: Pack this in somewhere... */
  65. u8 bucket;
  66. unsigned long used[1]; /* One bit per element. */
  67. };
  68. /* 2 bit for every byte to allocate. */
  69. static void tiny_alloc_init(void *pool, unsigned long poolsize)
  70. {
  71. /* FIXME */
  72. }
  73. static void *tiny_alloc_get(void *pool, unsigned long poolsize,
  74. unsigned long size, unsigned long align)
  75. {
  76. /* FIXME */
  77. return NULL;
  78. }
  79. static void tiny_alloc_free(void *pool, unsigned long poolsize, void *free)
  80. {
  81. /* FIXME */
  82. }
  83. static unsigned long tiny_alloc_size(void *pool, unsigned long poolsize,
  84. void *p)
  85. {
  86. /* FIXME */
  87. return 0;
  88. }
  89. static bool tiny_alloc_check(void *pool, unsigned long poolsize)
  90. {
  91. /* FIXME */
  92. return true;
  93. }
  94. static unsigned int fls(unsigned long val)
  95. {
  96. #if HAVE_BUILTIN_CLZL
  97. /* This is significantly faster! */
  98. return val ? sizeof(long) * CHAR_BIT - __builtin_clzl(val) : 0;
  99. #else
  100. unsigned int r = 32;
  101. if (!val)
  102. return 0;
  103. if (!(val & 0xffff0000u)) {
  104. val <<= 16;
  105. r -= 16;
  106. }
  107. if (!(val & 0xff000000u)) {
  108. val <<= 8;
  109. r -= 8;
  110. }
  111. if (!(val & 0xf0000000u)) {
  112. val <<= 4;
  113. r -= 4;
  114. }
  115. if (!(val & 0xc0000000u)) {
  116. val <<= 2;
  117. r -= 2;
  118. }
  119. if (!(val & 0x80000000u)) {
  120. val <<= 1;
  121. r -= 1;
  122. }
  123. return r;
  124. #endif
  125. }
  126. /* FIXME: Move to bitops. */
  127. static unsigned int ffsl(unsigned long val)
  128. {
  129. #if HAVE_BUILTIN_FFSL
  130. /* This is significantly faster! */
  131. return __builtin_ffsl(val);
  132. #else
  133. unsigned int r = 1;
  134. if (!val)
  135. return 0;
  136. if (sizeof(long) == sizeof(u64)) {
  137. if (!(val & 0xffffffff)) {
  138. /* Workaround gcc warning on 32-bit:
  139. error: right shift count >= width of type */
  140. u64 tmp = val;
  141. tmp >>= 32;
  142. val = tmp;
  143. r += 32;
  144. }
  145. }
  146. if (!(val & 0xffff)) {
  147. val >>= 16;
  148. r += 16;
  149. }
  150. if (!(val & 0xff)) {
  151. val >>= 8;
  152. r += 8;
  153. }
  154. if (!(val & 0xf)) {
  155. val >>= 4;
  156. r += 4;
  157. }
  158. if (!(val & 3)) {
  159. val >>= 2;
  160. r += 2;
  161. }
  162. if (!(val & 1)) {
  163. val >>= 1;
  164. r += 1;
  165. }
  166. return r;
  167. #endif
  168. }
  169. static unsigned int popcount(unsigned long val)
  170. {
  171. #if HAVE_BUILTIN_POPCOUNTL
  172. return __builtin_popcountl(val);
  173. #else
  174. if (sizeof(long) == sizeof(u64)) {
  175. u64 v = val;
  176. v = (v & 0x5555555555555555ULL)
  177. + ((v >> 1) & 0x5555555555555555ULL);
  178. v = (v & 0x3333333333333333ULL)
  179. + ((v >> 1) & 0x3333333333333333ULL);
  180. v = (v & 0x0F0F0F0F0F0F0F0FULL)
  181. + ((v >> 1) & 0x0F0F0F0F0F0F0F0FULL);
  182. v = (v & 0x00FF00FF00FF00FFULL)
  183. + ((v >> 1) & 0x00FF00FF00FF00FFULL);
  184. v = (v & 0x0000FFFF0000FFFFULL)
  185. + ((v >> 1) & 0x0000FFFF0000FFFFULL);
  186. v = (v & 0x00000000FFFFFFFFULL)
  187. + ((v >> 1) & 0x00000000FFFFFFFFULL);
  188. return v;
  189. }
  190. val = (val & 0x55555555ULL) + ((val >> 1) & 0x55555555ULL);
  191. val = (val & 0x33333333ULL) + ((val >> 1) & 0x33333333ULL);
  192. val = (val & 0x0F0F0F0FULL) + ((val >> 1) & 0x0F0F0F0FULL);
  193. val = (val & 0x00FF00FFULL) + ((val >> 1) & 0x00FF00FFULL);
  194. val = (val & 0x0000FFFFULL) + ((val >> 1) & 0x0000FFFFULL);
  195. return val;
  196. #endif
  197. }
  198. /*
  199. * Every 4 buckets, the size doubles.
  200. * Between buckets, sizes increase linearly.
  201. *
  202. * eg. bucket 40 = 2^10 = 1024
  203. * bucket 41 = 2^10 + 2^10*4 = 1024 + 256
  204. * bucket 42 = 2^10 + 2^10*4 = 1024 + 512
  205. * bucket 43 = 2^10 + 2^10*4 = 1024 + 768
  206. * bucket 45 = 2^11 = 2048
  207. *
  208. * Care is taken to handle low numbered buckets, at cost of overflow.
  209. */
  210. static unsigned long bucket_to_size(unsigned int bucket)
  211. {
  212. unsigned long base = 1 << (bucket / INTER_BUCKET_SPACE);
  213. return base + ((bucket % INTER_BUCKET_SPACE)
  214. << (bucket / INTER_BUCKET_SPACE))
  215. / INTER_BUCKET_SPACE;
  216. }
  217. /*
  218. * Say size is 10.
  219. * fls(size/2) == 3. 1 << 3 == 8, so we're 2 too large, out of a possible
  220. * 8 too large. That's 1/4 of the way to the next power of 2 == 1 bucket.
  221. *
  222. * We make sure we round up. Note that this fails on 32 bit at size
  223. * 1879048193 (around bucket 120).
  224. */
  225. static unsigned int size_to_bucket(unsigned long size)
  226. {
  227. unsigned int base = fls(size/2);
  228. unsigned long overshoot;
  229. overshoot = size - (1 << base);
  230. return base * INTER_BUCKET_SPACE
  231. + ((overshoot * INTER_BUCKET_SPACE + (1 << base)-1) >> base);
  232. }
  233. static unsigned int large_page_bits(unsigned long poolsize)
  234. {
  235. return fls(poolsize / MAX_PAGES / 2);
  236. }
  237. static unsigned long align_up(unsigned long x, unsigned long align)
  238. {
  239. return (x + align - 1) & ~(align - 1);
  240. }
  241. static struct page_header *from_off(struct header *head, unsigned long off)
  242. {
  243. return (struct page_header *)((char *)head + off);
  244. }
  245. static unsigned long to_off(struct header *head, void *p)
  246. {
  247. return (char *)p - (char *)head;
  248. }
  249. static size_t used_size(unsigned int num_elements)
  250. {
  251. return align_up(num_elements, BITS_PER_LONG) / CHAR_BIT;
  252. }
  253. /*
  254. * We always align the first entry to the lower power of 2.
  255. * eg. the 12-byte bucket gets 8-byte aligned. The 4096-byte bucket
  256. * gets 4096-byte aligned.
  257. */
  258. static unsigned long page_header_size(unsigned int align_bits,
  259. unsigned long num_elements)
  260. {
  261. unsigned long size;
  262. size = sizeof(struct page_header)
  263. - sizeof(((struct page_header *)0)->used)
  264. + used_size(num_elements);
  265. return align_up(size, 1 << align_bits);
  266. }
  267. static void add_to_list(struct header *head,
  268. unsigned long *list, struct page_header *ph)
  269. {
  270. unsigned long h = *list, offset = to_off(head, ph);
  271. ph->next = h;
  272. if (h) {
  273. struct page_header *prev = from_off(head, h);
  274. assert(prev->prev == 0);
  275. prev->prev = offset;
  276. }
  277. *list = offset;
  278. ph->prev = 0;
  279. }
  280. static void del_from_list(struct header *head,
  281. unsigned long *list, struct page_header *ph)
  282. {
  283. /* Front of list? */
  284. if (ph->prev == 0) {
  285. *list = ph->next;
  286. } else {
  287. struct page_header *prev = from_off(head, ph->prev);
  288. prev->next = ph->next;
  289. }
  290. if (ph->next != 0) {
  291. struct page_header *next = from_off(head, ph->next);
  292. next->prev = ph->prev;
  293. }
  294. }
  295. static unsigned long pop_from_list(struct header *head,
  296. unsigned long *list)
  297. {
  298. unsigned long h = *list;
  299. struct page_header *ph = from_off(head, h);
  300. if (likely(h)) {
  301. *list = ph->next;
  302. if (*list) {
  303. struct page_header *next = from_off(head, *list);
  304. next->prev = 0;
  305. }
  306. }
  307. return h;
  308. }
  309. static void add_small_page_to_freelist(struct header *head,
  310. struct page_header *ph)
  311. {
  312. add_to_list(head, &head->small_free_list, ph);
  313. }
  314. static void add_large_page_to_freelist(struct header *head,
  315. struct page_header *ph)
  316. {
  317. add_to_list(head, &head->large_free_list, ph);
  318. }
  319. static void add_to_bucket_list(struct header *head,
  320. struct bucket_state *bs,
  321. struct page_header *ph)
  322. {
  323. add_to_list(head, &bs->page_list, ph);
  324. }
  325. static void del_from_bucket_list(struct header *head,
  326. struct bucket_state *bs,
  327. struct page_header *ph)
  328. {
  329. del_from_list(head, &bs->page_list, ph);
  330. }
  331. static void del_from_bucket_full_list(struct header *head,
  332. struct bucket_state *bs,
  333. struct page_header *ph)
  334. {
  335. del_from_list(head, &bs->full_list, ph);
  336. }
  337. static void add_to_bucket_full_list(struct header *head,
  338. struct bucket_state *bs,
  339. struct page_header *ph)
  340. {
  341. add_to_list(head, &bs->full_list, ph);
  342. }
  343. static void clear_bit(unsigned long bitmap[], unsigned int off)
  344. {
  345. bitmap[off / BITS_PER_LONG] &= ~(1 << (off % BITS_PER_LONG));
  346. }
  347. static bool test_bit(const unsigned long bitmap[], unsigned int off)
  348. {
  349. return bitmap[off / BITS_PER_LONG] & (1 << (off % BITS_PER_LONG));
  350. }
  351. static void set_bit(unsigned long bitmap[], unsigned int off)
  352. {
  353. bitmap[off / BITS_PER_LONG] |= (1 << (off % BITS_PER_LONG));
  354. }
  355. /* There must be a bit to be found. */
  356. static unsigned int find_free_bit(const unsigned long bitmap[])
  357. {
  358. unsigned int i;
  359. for (i = 0; bitmap[i] == -1UL; i++);
  360. return (i*BITS_PER_LONG) + ffsl(~bitmap[i]) - 1;
  361. }
  362. /* How many elements can we fit in a page? */
  363. static unsigned long elements_per_page(unsigned long align_bits,
  364. unsigned long esize,
  365. unsigned long psize)
  366. {
  367. unsigned long num, overhead;
  368. /* First approximation: no extra room for bitmap. */
  369. overhead = align_up(sizeof(struct page_header), 1 << align_bits);
  370. num = (psize - overhead) / esize;
  371. while (page_header_size(align_bits, num) + esize * num > psize)
  372. num--;
  373. return num;
  374. }
  375. static bool large_page_bucket(unsigned int bucket, unsigned long poolsize)
  376. {
  377. unsigned int sp_bits;
  378. unsigned long max_smallsize;
  379. sp_bits = large_page_bits(poolsize) - BITS_FROM_SMALL_TO_LARGE_PAGE;
  380. /* Note: this doesn't take into account page header. */
  381. max_smallsize = (1UL << sp_bits) >> MAX_PAGE_OBJECT_ORDER;
  382. return bucket_to_size(bucket) > max_smallsize;
  383. }
  384. static unsigned int max_bucket(unsigned int lp_bits)
  385. {
  386. return (lp_bits - MAX_PAGE_OBJECT_ORDER) * INTER_BUCKET_SPACE;
  387. }
  388. void alloc_init(void *pool, unsigned long poolsize)
  389. {
  390. struct header *head = pool;
  391. struct page_header *ph;
  392. unsigned int lp_bits, sp_bits, num_buckets;
  393. unsigned long header_size, i;
  394. if (poolsize < MIN_USEFUL_SIZE) {
  395. tiny_alloc_init(pool, poolsize);
  396. return;
  397. }
  398. lp_bits = large_page_bits(poolsize);
  399. sp_bits = lp_bits - BITS_FROM_SMALL_TO_LARGE_PAGE;
  400. num_buckets = max_bucket(lp_bits);
  401. head = pool;
  402. header_size = sizeof(*head) + sizeof(head->bs) * (num_buckets-1);
  403. memset(head, 0, header_size);
  404. for (i = 0; i < num_buckets; i++) {
  405. unsigned long pagesize;
  406. if (large_page_bucket(i, poolsize))
  407. pagesize = 1UL << lp_bits;
  408. else
  409. pagesize = 1UL << sp_bits;
  410. head->bs[i].elements_per_page
  411. = elements_per_page(i / INTER_BUCKET_SPACE,
  412. bucket_to_size(i),
  413. pagesize);
  414. }
  415. /* They start as all large pages. */
  416. memset(head->pagesize, 0xFF, sizeof(head->pagesize));
  417. /* FIXME: small pages for last bit? */
  418. /* Split first page into small pages. */
  419. assert(header_size << (1UL << lp_bits));
  420. clear_bit(head->pagesize, 0);
  421. /* Skip over page(s) used by header, add rest to free list */
  422. for (i = align_up(header_size, (1 << sp_bits)) >> sp_bits;
  423. i < (1 << BITS_FROM_SMALL_TO_LARGE_PAGE);
  424. i++) {
  425. ph = from_off(head, i<<sp_bits);
  426. ph->elements_used = 0;
  427. add_small_page_to_freelist(head, ph);
  428. }
  429. /* Add the rest of the pages as large pages. */
  430. i = (1 << lp_bits);
  431. while (i + (1 << lp_bits) <= poolsize) {
  432. ph = from_off(head, i);
  433. ph->elements_used = 0;
  434. add_large_page_to_freelist(head, ph);
  435. i += (1 << lp_bits);
  436. }
  437. }
  438. /* A large page worth of small pages are free: delete them from free list. */
  439. static void del_large_from_small_free_list(struct header *head,
  440. struct page_header *ph,
  441. unsigned int sp_bits)
  442. {
  443. unsigned long i;
  444. for (i = 0; i < (1 << BITS_FROM_SMALL_TO_LARGE_PAGE); i++) {
  445. del_from_list(head, &head->small_free_list,
  446. (void *)ph + (i << sp_bits));
  447. }
  448. }
  449. static bool all_empty(struct header *head, unsigned long off, unsigned sp_bits)
  450. {
  451. unsigned long i;
  452. for (i = 0; i < (1 << BITS_FROM_SMALL_TO_LARGE_PAGE); i++) {
  453. struct page_header *ph = from_off(head, off + (i << sp_bits));
  454. if (ph->elements_used)
  455. return false;
  456. }
  457. return true;
  458. }
  459. static unsigned long get_large_page(struct header *head,
  460. unsigned long poolsize)
  461. {
  462. unsigned long lp_bits, sp_bits, i, page;
  463. page = pop_from_list(head, &head->large_free_list);
  464. if (likely(page))
  465. return page;
  466. /* Look for small pages to coalesce, after first large page. */
  467. lp_bits = large_page_bits(poolsize);
  468. sp_bits = lp_bits - BITS_FROM_SMALL_TO_LARGE_PAGE;
  469. for (i = (1 << lp_bits); i < poolsize; i += (1 << lp_bits)) {
  470. /* Already a large page? */
  471. if (test_bit(head->pagesize, i >> lp_bits))
  472. continue;
  473. if (all_empty(head, i, sp_bits)) {
  474. struct page_header *ph = from_off(head, i);
  475. set_bit(head->pagesize, i >> lp_bits);
  476. del_large_from_small_free_list(head, ph, sp_bits);
  477. add_large_page_to_freelist(head, ph);
  478. }
  479. }
  480. return pop_from_list(head, &head->large_free_list);
  481. }
  482. /* Returns small page. */
  483. static unsigned long break_up_large_page(struct header *head,
  484. unsigned long psize,
  485. unsigned long lpage)
  486. {
  487. unsigned long lp_bits, sp_bits, i;
  488. lp_bits = large_page_bits(psize);
  489. sp_bits = lp_bits - BITS_FROM_SMALL_TO_LARGE_PAGE;
  490. clear_bit(head->pagesize, lpage >> lp_bits);
  491. for (i = 1; i < (1 << BITS_FROM_SMALL_TO_LARGE_PAGE); i++)
  492. add_small_page_to_freelist(head,
  493. from_off(head,
  494. lpage + (i<<sp_bits)));
  495. return lpage;
  496. }
  497. static unsigned long get_small_page(struct header *head,
  498. unsigned long poolsize)
  499. {
  500. unsigned long ret;
  501. ret = pop_from_list(head, &head->small_free_list);
  502. if (likely(ret))
  503. return ret;
  504. ret = get_large_page(head, poolsize);
  505. if (likely(ret))
  506. ret = break_up_large_page(head, poolsize, ret);
  507. return ret;
  508. }
  509. void *alloc_get(void *pool, unsigned long poolsize,
  510. unsigned long size, unsigned long align)
  511. {
  512. struct header *head = pool;
  513. unsigned int bucket;
  514. unsigned long i;
  515. struct bucket_state *bs;
  516. struct page_header *ph;
  517. if (poolsize < MIN_USEFUL_SIZE) {
  518. return tiny_alloc_get(pool, poolsize, size, align);
  519. }
  520. size = align_up(size, align);
  521. if (unlikely(!size))
  522. size = 1;
  523. bucket = size_to_bucket(size);
  524. if (bucket >= max_bucket(large_page_bits(poolsize))) {
  525. /* FIXME: huge alloc. */
  526. return NULL;
  527. }
  528. bs = &head->bs[bucket];
  529. if (!bs->page_list) {
  530. struct page_header *ph;
  531. if (large_page_bucket(bucket, poolsize))
  532. bs->page_list = get_large_page(head, poolsize);
  533. else
  534. bs->page_list = get_small_page(head, poolsize);
  535. /* FIXME: Try large-aligned alloc? Header stuffing? */
  536. if (unlikely(!bs->page_list))
  537. return NULL;
  538. ph = from_off(head, bs->page_list);
  539. ph->bucket = bucket;
  540. ph->elements_used = 0;
  541. ph->next = 0;
  542. memset(ph->used, 0, used_size(bs->elements_per_page));
  543. }
  544. ph = from_off(head, bs->page_list);
  545. i = find_free_bit(ph->used);
  546. set_bit(ph->used, i);
  547. ph->elements_used++;
  548. /* check if this page is now full */
  549. if (unlikely(ph->elements_used == bs->elements_per_page)) {
  550. del_from_bucket_list(head, bs, ph);
  551. add_to_bucket_full_list(head, bs, ph);
  552. }
  553. return (char *)ph + page_header_size(ph->bucket / INTER_BUCKET_SPACE,
  554. bs->elements_per_page)
  555. + i * bucket_to_size(bucket);
  556. }
  557. void alloc_free(void *pool, unsigned long poolsize, void *free)
  558. {
  559. struct header *head = pool;
  560. struct bucket_state *bs;
  561. unsigned int pagebits;
  562. unsigned long i, pgoffset, offset = (char *)free - (char *)pool;
  563. bool smallpage;
  564. struct page_header *ph;
  565. if (poolsize < MIN_USEFUL_SIZE) {
  566. return tiny_alloc_free(pool, poolsize, free);
  567. }
  568. /* Get page header. */
  569. pagebits = large_page_bits(poolsize);
  570. if (!test_bit(head->pagesize, offset >> pagebits)) {
  571. smallpage = true;
  572. pagebits -= BITS_FROM_SMALL_TO_LARGE_PAGE;
  573. } else
  574. smallpage = false;
  575. /* Step back to page header. */
  576. ph = from_off(head, offset & ~((1UL << pagebits) - 1));
  577. bs = &head->bs[ph->bucket];
  578. pgoffset = (offset & ((1UL << pagebits) - 1))
  579. - page_header_size(ph->bucket / INTER_BUCKET_SPACE,
  580. bs->elements_per_page);
  581. if (unlikely(ph->elements_used == bs->elements_per_page)) {
  582. del_from_bucket_full_list(head, bs, ph);
  583. add_to_bucket_list(head, bs, ph);
  584. }
  585. /* Which element are we? */
  586. i = pgoffset / bucket_to_size(ph->bucket);
  587. clear_bit(ph->used, i);
  588. ph->elements_used--;
  589. if (unlikely(ph->elements_used == 0)) {
  590. bs = &head->bs[ph->bucket];
  591. del_from_bucket_list(head, bs, ph);
  592. if (smallpage)
  593. add_small_page_to_freelist(head, ph);
  594. else
  595. add_large_page_to_freelist(head, ph);
  596. }
  597. }
  598. unsigned long alloc_size(void *pool, unsigned long poolsize, void *p)
  599. {
  600. struct header *head = pool;
  601. unsigned int pagebits;
  602. unsigned long offset = (char *)p - (char *)pool;
  603. struct page_header *ph;
  604. if (poolsize < MIN_USEFUL_SIZE)
  605. return tiny_alloc_size(pool, poolsize, p);
  606. /* Get page header. */
  607. pagebits = large_page_bits(poolsize);
  608. if (!test_bit(head->pagesize, offset >> pagebits))
  609. pagebits -= BITS_FROM_SMALL_TO_LARGE_PAGE;
  610. /* Step back to page header. */
  611. ph = from_off(head, offset & ~((1UL << pagebits) - 1));
  612. return bucket_to_size(ph->bucket);
  613. }
  614. /* Useful for gdb breakpoints. */
  615. static bool check_fail(void)
  616. {
  617. return false;
  618. }
  619. static unsigned long count_bits(const unsigned long bitmap[],
  620. unsigned long limit)
  621. {
  622. unsigned long i, count = 0;
  623. while (limit >= BITS_PER_LONG) {
  624. count += popcount(bitmap[0]);
  625. bitmap++;
  626. limit -= BITS_PER_LONG;
  627. }
  628. for (i = 0; i < limit; i++)
  629. if (test_bit(bitmap, i))
  630. count++;
  631. return count;
  632. }
  633. static bool out_of_bounds(unsigned long off,
  634. unsigned long pagesize,
  635. unsigned long poolsize)
  636. {
  637. return (off > poolsize || off + pagesize > poolsize);
  638. }
  639. static bool check_bucket(struct header *head,
  640. unsigned long poolsize,
  641. unsigned long pages[],
  642. struct bucket_state *bs,
  643. unsigned int bindex)
  644. {
  645. bool lp_bucket = large_page_bucket(bindex, poolsize);
  646. struct page_header *ph;
  647. unsigned long taken, i, prev, pagesize, sp_bits, lp_bits;
  648. lp_bits = large_page_bits(poolsize);
  649. sp_bits = lp_bits - BITS_FROM_SMALL_TO_LARGE_PAGE;
  650. pagesize = 1UL << (lp_bucket ? lp_bits : sp_bits);
  651. /* This many elements fit? */
  652. taken = page_header_size(bindex / INTER_BUCKET_SPACE,
  653. bs->elements_per_page);
  654. taken += bucket_to_size(bindex) * bs->elements_per_page;
  655. if (taken > pagesize)
  656. return check_fail();
  657. /* One more wouldn't fit? */
  658. taken = page_header_size(bindex / INTER_BUCKET_SPACE,
  659. bs->elements_per_page + 1);
  660. taken += bucket_to_size(bindex) * (bs->elements_per_page + 1);
  661. if (taken <= pagesize)
  662. return check_fail();
  663. /* Walk used list. */
  664. prev = 0;
  665. for (i = bs->page_list; i; i = ph->next) {
  666. /* Bad pointer? */
  667. if (out_of_bounds(i, pagesize, poolsize))
  668. return check_fail();
  669. /* Wrong size page? */
  670. if (!!test_bit(head->pagesize, i >> lp_bits) != lp_bucket)
  671. return check_fail();
  672. /* Not page boundary? */
  673. if (i % pagesize)
  674. return check_fail();
  675. ph = from_off(head, i);
  676. /* Linked list corrupt? */
  677. if (ph->prev != prev)
  678. return check_fail();
  679. /* Already seen this page? */
  680. if (test_bit(pages, i >> sp_bits))
  681. return check_fail();
  682. set_bit(pages, i >> sp_bits);
  683. /* Empty or full? */
  684. if (ph->elements_used == 0)
  685. return check_fail();
  686. if (ph->elements_used >= bs->elements_per_page)
  687. return check_fail();
  688. /* Used bits don't agree? */
  689. if (ph->elements_used != count_bits(ph->used,
  690. bs->elements_per_page))
  691. return check_fail();
  692. /* Wrong bucket? */
  693. if (ph->bucket != bindex)
  694. return check_fail();
  695. prev = i;
  696. }
  697. /* Walk full list. */
  698. prev = 0;
  699. for (i = bs->full_list; i; i = ph->next) {
  700. /* Bad pointer? */
  701. if (out_of_bounds(i, pagesize, poolsize))
  702. return check_fail();
  703. /* Wrong size page? */
  704. if (!!test_bit(head->pagesize, i >> lp_bits) != lp_bucket)
  705. return check_fail();
  706. /* Not page boundary? */
  707. if (i % pagesize)
  708. return check_fail();
  709. ph = from_off(head, i);
  710. /* Linked list corrupt? */
  711. if (ph->prev != prev)
  712. return check_fail();
  713. /* Already seen this page? */
  714. if (test_bit(pages, i >> sp_bits))
  715. return check_fail();
  716. set_bit(pages, i >> sp_bits);
  717. /* Not full? */
  718. if (ph->elements_used != bs->elements_per_page)
  719. return check_fail();
  720. /* Used bits don't agree? */
  721. if (ph->elements_used != count_bits(ph->used,
  722. bs->elements_per_page))
  723. return check_fail();
  724. /* Wrong bucket? */
  725. if (ph->bucket != bindex)
  726. return check_fail();
  727. prev = i;
  728. }
  729. return true;
  730. }
  731. bool alloc_check(void *pool, unsigned long poolsize)
  732. {
  733. struct header *head = pool;
  734. unsigned long prev, i, lp_bits, sp_bits, header_size, num_buckets;
  735. struct page_header *ph;
  736. unsigned long pages[(MAX_PAGES << BITS_FROM_SMALL_TO_LARGE_PAGE)
  737. / BITS_PER_LONG] = { 0 };
  738. if (poolsize < MIN_USEFUL_SIZE)
  739. return tiny_alloc_check(pool, poolsize);
  740. lp_bits = large_page_bits(poolsize);
  741. sp_bits = lp_bits - BITS_FROM_SMALL_TO_LARGE_PAGE;
  742. num_buckets = max_bucket(lp_bits);
  743. header_size = sizeof(*head) + sizeof(head->bs) * (num_buckets-1);
  744. /* First, set all bits taken by header. */
  745. for (i = 0; i < header_size; i += (1UL << sp_bits))
  746. set_bit(pages, i >> sp_bits);
  747. /* Check small page free list. */
  748. prev = 0;
  749. for (i = head->small_free_list; i; i = ph->next) {
  750. /* Bad pointer? */
  751. if (out_of_bounds(i, 1 << sp_bits, poolsize))
  752. return check_fail();
  753. /* Large page? */
  754. if (test_bit(head->pagesize, i >> lp_bits))
  755. return check_fail();
  756. /* Not page boundary? */
  757. if (i % (1 << sp_bits))
  758. return check_fail();
  759. ph = from_off(head, i);
  760. /* Linked list corrupt? */
  761. if (ph->prev != prev)
  762. return check_fail();
  763. /* Already seen this page? */
  764. if (test_bit(pages, i >> sp_bits))
  765. return check_fail();
  766. set_bit(pages, i >> sp_bits);
  767. prev = i;
  768. }
  769. /* Check large page free list. */
  770. prev = 0;
  771. for (i = head->large_free_list; i; i = ph->next) {
  772. /* Bad pointer? */
  773. if (out_of_bounds(i, 1 << lp_bits, poolsize))
  774. return check_fail();
  775. /* Not large page? */
  776. if (!test_bit(head->pagesize, i >> lp_bits))
  777. return check_fail();
  778. /* Not page boundary? */
  779. if (i % (1 << lp_bits))
  780. return check_fail();
  781. ph = from_off(head, i);
  782. /* Linked list corrupt? */
  783. if (ph->prev != prev)
  784. return check_fail();
  785. /* Already seen this page? */
  786. if (test_bit(pages, i >> sp_bits))
  787. return check_fail();
  788. set_bit(pages, i >> sp_bits);
  789. prev = i;
  790. }
  791. /* Check the buckets. */
  792. for (i = 0; i < max_bucket(lp_bits); i++) {
  793. struct bucket_state *bs = &head->bs[i];
  794. if (!check_bucket(head, poolsize, pages, bs, i))
  795. return false;
  796. }
  797. /* Make sure every page accounted for. */
  798. for (i = 0; i < poolsize >> sp_bits; i++) {
  799. if (!test_bit(pages, i))
  800. return check_fail();
  801. if (test_bit(head->pagesize,
  802. i >> BITS_FROM_SMALL_TO_LARGE_PAGE)) {
  803. /* Large page, skip rest. */
  804. i += (1 << BITS_FROM_SMALL_TO_LARGE_PAGE) - 1;
  805. }
  806. }
  807. return true;
  808. }