162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2000-2005 Silicon Graphics, Inc.
462306a36Sopenharmony_ci * All Rights Reserved.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci#ifndef __XFS_SUPPORT_KMEM_H__
762306a36Sopenharmony_ci#define __XFS_SUPPORT_KMEM_H__
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/slab.h>
1062306a36Sopenharmony_ci#include <linux/sched.h>
1162306a36Sopenharmony_ci#include <linux/mm.h>
1262306a36Sopenharmony_ci#include <linux/vmalloc.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci/*
1562306a36Sopenharmony_ci * General memory allocation interfaces
1662306a36Sopenharmony_ci */
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_citypedef unsigned __bitwise xfs_km_flags_t;
1962306a36Sopenharmony_ci#define KM_NOFS		((__force xfs_km_flags_t)0x0004u)
2062306a36Sopenharmony_ci#define KM_MAYFAIL	((__force xfs_km_flags_t)0x0008u)
2162306a36Sopenharmony_ci#define KM_ZERO		((__force xfs_km_flags_t)0x0010u)
2262306a36Sopenharmony_ci#define KM_NOLOCKDEP	((__force xfs_km_flags_t)0x0020u)
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci/*
2562306a36Sopenharmony_ci * We use a special process flag to avoid recursive callbacks into
2662306a36Sopenharmony_ci * the filesystem during transactions.  We will also issue our own
2762306a36Sopenharmony_ci * warnings, so we explicitly skip any generic ones (silly of us).
2862306a36Sopenharmony_ci */
2962306a36Sopenharmony_cistatic inline gfp_t
3062306a36Sopenharmony_cikmem_flags_convert(xfs_km_flags_t flags)
3162306a36Sopenharmony_ci{
3262306a36Sopenharmony_ci	gfp_t	lflags;
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci	BUG_ON(flags & ~(KM_NOFS | KM_MAYFAIL | KM_ZERO | KM_NOLOCKDEP));
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	lflags = GFP_KERNEL | __GFP_NOWARN;
3762306a36Sopenharmony_ci	if (flags & KM_NOFS)
3862306a36Sopenharmony_ci		lflags &= ~__GFP_FS;
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci	/*
4162306a36Sopenharmony_ci	 * Default page/slab allocator behavior is to retry for ever
4262306a36Sopenharmony_ci	 * for small allocations. We can override this behavior by using
4362306a36Sopenharmony_ci	 * __GFP_RETRY_MAYFAIL which will tell the allocator to retry as long
4462306a36Sopenharmony_ci	 * as it is feasible but rather fail than retry forever for all
4562306a36Sopenharmony_ci	 * request sizes.
4662306a36Sopenharmony_ci	 */
4762306a36Sopenharmony_ci	if (flags & KM_MAYFAIL)
4862306a36Sopenharmony_ci		lflags |= __GFP_RETRY_MAYFAIL;
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	if (flags & KM_ZERO)
5162306a36Sopenharmony_ci		lflags |= __GFP_ZERO;
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	if (flags & KM_NOLOCKDEP)
5462306a36Sopenharmony_ci		lflags |= __GFP_NOLOCKDEP;
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	return lflags;
5762306a36Sopenharmony_ci}
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ciextern void *kmem_alloc(size_t, xfs_km_flags_t);
6062306a36Sopenharmony_cistatic inline void  kmem_free(const void *ptr)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	kvfree(ptr);
6362306a36Sopenharmony_ci}
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_cistatic inline void *
6762306a36Sopenharmony_cikmem_zalloc(size_t size, xfs_km_flags_t flags)
6862306a36Sopenharmony_ci{
6962306a36Sopenharmony_ci	return kmem_alloc(size, flags | KM_ZERO);
7062306a36Sopenharmony_ci}
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci/*
7362306a36Sopenharmony_ci * Zone interfaces
7462306a36Sopenharmony_ci */
7562306a36Sopenharmony_cistatic inline struct page *
7662306a36Sopenharmony_cikmem_to_page(void *addr)
7762306a36Sopenharmony_ci{
7862306a36Sopenharmony_ci	if (is_vmalloc_addr(addr))
7962306a36Sopenharmony_ci		return vmalloc_to_page(addr);
8062306a36Sopenharmony_ci	return virt_to_page(addr);
8162306a36Sopenharmony_ci}
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci#endif /* __XFS_SUPPORT_KMEM_H__ */
84