quicklist.h 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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. q = &get_cpu_var(quicklist)[nr];
  53. *(void **)p = q->page;
  54. q->page = p;
  55. q->nr_pages++;
  56. put_cpu_var(quicklist);
  57. }
  58. static inline void quicklist_free(int nr, void (*dtor)(void *), void *pp)
  59. {
  60. __quicklist_free(nr, dtor, pp, virt_to_page(pp));
  61. }
  62. static inline void quicklist_free_page(int nr, void (*dtor)(void *),
  63. struct page *page)
  64. {
  65. __quicklist_free(nr, dtor, page_address(page), page);
  66. }
  67. void quicklist_trim(int nr, void (*dtor)(void *),
  68. unsigned long min_pages, unsigned long max_free);
  69. unsigned long quicklist_total_size(void);
  70. #else
  71. static inline unsigned long quicklist_total_size(void)
  72. {
  73. return 0;
  74. }
  75. #endif
  76. #endif /* LINUX_QUICKLIST_H */