page.h 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. #ifndef _ASM_GENERIC_PAGE_H
  2. #define _ASM_GENERIC_PAGE_H
  3. #ifdef __KERNEL__
  4. #ifndef __ASSEMBLY__
  5. #include <linux/log2.h>
  6. /*
  7. * non-const pure 2^n version of get_order
  8. * - the arch may override these in asm/bitops.h if they can be implemented
  9. * more efficiently than using the arch log2 routines
  10. * - we use the non-const log2() instead if the arch has defined one suitable
  11. */
  12. #ifndef ARCH_HAS_GET_ORDER
  13. static inline __attribute__((const))
  14. int __get_order(unsigned long size, int page_shift)
  15. {
  16. #if BITS_PER_LONG == 32 && defined(ARCH_HAS_ILOG2_U32)
  17. int order = __ilog2_u32(size) - page_shift;
  18. return order >= 0 ? order : 0;
  19. #elif BITS_PER_LONG == 64 && defined(ARCH_HAS_ILOG2_U64)
  20. int order = __ilog2_u64(size) - page_shift;
  21. return order >= 0 ? order : 0;
  22. #else
  23. int order;
  24. size = (size - 1) >> (page_shift - 1);
  25. order = -1;
  26. do {
  27. size >>= 1;
  28. order++;
  29. } while (size);
  30. return order;
  31. #endif
  32. }
  33. #endif
  34. /**
  35. * get_order - calculate log2(pages) to hold a block of the specified size
  36. * @n - size
  37. *
  38. * calculate allocation order based on the current page size
  39. * - this can be used to initialise global variables from constant data
  40. */
  41. #define get_order(n) \
  42. ( \
  43. __builtin_constant_p(n) ? \
  44. ((n < (1UL << PAGE_SHIFT)) ? 0 : ilog2(n) - PAGE_SHIFT) : \
  45. __get_order(n, PAGE_SHIFT) \
  46. )
  47. #endif /* __ASSEMBLY__ */
  48. #endif /* __KERNEL__ */
  49. #endif /* _ASM_GENERIC_PAGE_H */