quicklist.h 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #ifndef LINUX_QUICKLIST_H
  2. #define LINUX_QUICKLIST_H
  3. /*
  4. * Fast allocations and disposal of pages. Pages must be in the condition
  5. * as needed after allocation when they are freed. Per cpu lists of pages
  6. * are kept that only contain node local pages.
  7. *
  8. * (C) 2007, SGI. Christoph Lameter <clameter@sgi.com>
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/gfp.h>
  12. #include <linux/percpu.h>
  13. #ifdef CONFIG_QUICKLIST
  14. struct quicklist {
  15. void *page;
  16. int nr_pages;
  17. };
  18. DECLARE_PER_CPU(struct quicklist, quicklist)[CONFIG_NR_QUICK];
  19. /*
  20. * The two key functions quicklist_alloc and quicklist_free are inline so
  21. * that they may be custom compiled for the platform.
  22. * Specifying a NULL ctor can remove constructor support. Specifying
  23. * a constant quicklist allows the determination of the exact address
  24. * in the per cpu area.
  25. *
  26. * The fast patch in quicklist_alloc touched only a per cpu cacheline and
  27. * the first cacheline of the page itself. There is minmal overhead involved.
  28. */
  29. static inline void *quicklist_alloc(int nr, gfp_t flags, void (*ctor)(void *))
  30. {
  31. struct quicklist *q;
  32. void **p = NULL;
  33. q =&get_cpu_var(quicklist)[nr];
  34. p = q->page;
  35. if (likely(p)) {
  36. q->page = p[0];
  37. p[0] = NULL;
  38. q->nr_pages--;
  39. }
  40. put_cpu_var(quicklist);
  41. if (likely(p))
  42. return p;
  43. p = (void *)__get_free_page(flags | __GFP_ZERO);
  44. if (ctor && p)
  45. ctor(p);
  46. return p;
  47. }
  48. static inline void __quicklist_free(int nr, void (*dtor)(void *), void *p,
  49. struct page *page)
  50. {
  51. struct quicklist *q;
  52. int nid = page_to_nid(page);
  53. if (unlikely(nid != numa_node_id())) {
  54. if (dtor)
  55. dtor(p);
  56. __free_page(page);
  57. return;
  58. }
  59. q = &get_cpu_var(quicklist)[nr];
  60. *(void **)p = q->page;
  61. q->page = p;
  62. q->nr_pages++;
  63. put_cpu_var(quicklist);
  64. }
  65. static inline void quicklist_free(int nr, void (*dtor)(void *), void *pp)
  66. {
  67. __quicklist_free(nr, dtor, pp, virt_to_page(pp));
  68. }
  69. static inline void quicklist_free_page(int nr, void (*dtor)(void *),
  70. struct page *page)
  71. {
  72. __quicklist_free(nr, dtor, page_address(page), page);
  73. }
  74. void quicklist_trim(int nr, void (*dtor)(void *),
  75. unsigned long min_pages, unsigned long max_free);
  76. unsigned long quicklist_total_size(void);
  77. #endif
  78. #endif /* LINUX_QUICKLIST_H */