xref: /linux/mm/cma.h (revision f088104d837a991c65e51fa30bb4196169b3244d)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
228b24c1fSSasha Levin #ifndef __MM_CMA_H__
328b24c1fSSasha Levin #define __MM_CMA_H__
428b24c1fSSasha Levin 
5a2b992c8SJakub Kicinski #include <linux/debugfs.h>
643ca106fSMinchan Kim #include <linux/kobject.h>
743ca106fSMinchan Kim 
843ca106fSMinchan Kim struct cma_kobject {
943ca106fSMinchan Kim 	struct kobject kobj;
1043ca106fSMinchan Kim 	struct cma *cma;
1143ca106fSMinchan Kim };
12a2b992c8SJakub Kicinski 
13c009da42SFrank van der Linden /*
14c009da42SFrank van der Linden  * Multi-range support. This can be useful if the size of the allocation
15c009da42SFrank van der Linden  * is not expected to be larger than the alignment (like with hugetlb_cma),
16c009da42SFrank van der Linden  * and the total amount of memory requested, while smaller than the total
17c009da42SFrank van der Linden  * amount of memory available, is large enough that it doesn't fit in a
18c009da42SFrank van der Linden  * single physical memory range because of memory holes.
1985abcd02SFrank van der Linden  *
2085abcd02SFrank van der Linden  * Fields:
2185abcd02SFrank van der Linden  *   @base_pfn: physical address of range
2285abcd02SFrank van der Linden  *   @early_pfn: first PFN not reserved through cma_reserve_early
2385abcd02SFrank van der Linden  *   @count: size of range
2485abcd02SFrank van der Linden  *   @bitmap: bitmap of allocated (1 << order_per_bit)-sized chunks.
25c009da42SFrank van der Linden  */
26c009da42SFrank van der Linden struct cma_memrange {
2728b24c1fSSasha Levin 	unsigned long base_pfn;
2828b24c1fSSasha Levin 	unsigned long count;
29*83b6d498SZhongkun He 	union {
30*83b6d498SZhongkun He 		unsigned long early_pfn;
3128b24c1fSSasha Levin 		unsigned long *bitmap;
32*83b6d498SZhongkun He 	};
33c009da42SFrank van der Linden #ifdef CONFIG_CMA_DEBUGFS
34c009da42SFrank van der Linden 	struct debugfs_u32_array dfs_bitmap;
35c009da42SFrank van der Linden #endif
36c009da42SFrank van der Linden };
37c009da42SFrank van der Linden #define CMA_MAX_RANGES 8
38c009da42SFrank van der Linden 
39c009da42SFrank van der Linden struct cma {
40c009da42SFrank van der Linden 	unsigned long   count;
41c009da42SFrank van der Linden 	unsigned long	available_count;
4228b24c1fSSasha Levin 	unsigned int order_per_bit; /* Order of pages represented by one bit */
430ef7dcacSMike Kravetz 	spinlock_t	lock;
4424ac6fb6SGe Yang 	struct mutex alloc_mutex;
4526b02a1fSSasha Levin #ifdef CONFIG_CMA_DEBUGFS
4626b02a1fSSasha Levin 	struct hlist_head mem_head;
4726b02a1fSSasha Levin 	spinlock_t mem_head_lock;
4826b02a1fSSasha Levin #endif
4918e98e56SBarry Song 	char name[CMA_MAX_NAME];
50c009da42SFrank van der Linden 	int nranges;
51c009da42SFrank van der Linden 	struct cma_memrange ranges[CMA_MAX_RANGES];
5243ca106fSMinchan Kim #ifdef CONFIG_CMA_SYSFS
5343ca106fSMinchan Kim 	/* the number of CMA page successful allocations */
5443ca106fSMinchan Kim 	atomic64_t nr_pages_succeeded;
5543ca106fSMinchan Kim 	/* the number of CMA page allocation failures */
5643ca106fSMinchan Kim 	atomic64_t nr_pages_failed;
57b9ad003aSAnshuman Khandual 	/* the number of CMA page released */
58b9ad003aSAnshuman Khandual 	atomic64_t nr_pages_released;
5943ca106fSMinchan Kim 	/* kobject requires dynamic object */
6043ca106fSMinchan Kim 	struct cma_kobject *cma_kobj;
6143ca106fSMinchan Kim #endif
629320fa27SFrank van der Linden 	unsigned long flags;
63b51d3db9SFrank van der Linden 	/* NUMA node (NUMA_NO_NODE if unspecified) */
64b51d3db9SFrank van der Linden 	int nid;
6528b24c1fSSasha Levin };
6628b24c1fSSasha Levin 
679320fa27SFrank van der Linden enum cma_flags {
689320fa27SFrank van der Linden 	CMA_RESERVE_PAGES_ON_ERROR,
699320fa27SFrank van der Linden 	CMA_ZONES_VALID,
709320fa27SFrank van der Linden 	CMA_ZONES_INVALID,
7185abcd02SFrank van der Linden 	CMA_ACTIVATED,
729320fa27SFrank van der Linden };
739320fa27SFrank van der Linden 
7428b24c1fSSasha Levin extern struct cma cma_areas[MAX_CMA_AREAS];
75afeac03cSJiale Yang extern unsigned int cma_area_count;
7628b24c1fSSasha Levin 
cma_bitmap_maxno(struct cma * cma,struct cma_memrange * cmr)77c009da42SFrank van der Linden static inline unsigned long cma_bitmap_maxno(struct cma *cma,
78c009da42SFrank van der Linden 		struct cma_memrange *cmr)
7928b24c1fSSasha Levin {
80c009da42SFrank van der Linden 	return cmr->count >> cma->order_per_bit;
8128b24c1fSSasha Levin }
8228b24c1fSSasha Levin 
8343ca106fSMinchan Kim #ifdef CONFIG_CMA_SYSFS
8443ca106fSMinchan Kim void cma_sysfs_account_success_pages(struct cma *cma, unsigned long nr_pages);
8543ca106fSMinchan Kim void cma_sysfs_account_fail_pages(struct cma *cma, unsigned long nr_pages);
86b9ad003aSAnshuman Khandual void cma_sysfs_account_release_pages(struct cma *cma, unsigned long nr_pages);
8743ca106fSMinchan Kim #else
cma_sysfs_account_success_pages(struct cma * cma,unsigned long nr_pages)8843ca106fSMinchan Kim static inline void cma_sysfs_account_success_pages(struct cma *cma,
8943ca106fSMinchan Kim 						   unsigned long nr_pages) {};
cma_sysfs_account_fail_pages(struct cma * cma,unsigned long nr_pages)9043ca106fSMinchan Kim static inline void cma_sysfs_account_fail_pages(struct cma *cma,
9143ca106fSMinchan Kim 						unsigned long nr_pages) {};
cma_sysfs_account_release_pages(struct cma * cma,unsigned long nr_pages)92b9ad003aSAnshuman Khandual static inline void cma_sysfs_account_release_pages(struct cma *cma,
93b9ad003aSAnshuman Khandual 						   unsigned long nr_pages) {};
9443ca106fSMinchan Kim #endif
9528b24c1fSSasha Levin #endif
96