#include <linux/iova.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/bitops.h>
#include <linux/cpu.h>
#include <linux/workqueue.h>
#define IOVA_ANCHOR …
#define IOVA_RANGE_CACHE_MAX_SIZE …
static bool iova_rcache_insert(struct iova_domain *iovad,
unsigned long pfn,
unsigned long size);
static unsigned long iova_rcache_get(struct iova_domain *iovad,
unsigned long size,
unsigned long limit_pfn);
static void free_iova_rcaches(struct iova_domain *iovad);
static void free_cpu_cached_iovas(unsigned int cpu, struct iova_domain *iovad);
static void free_global_cached_iovas(struct iova_domain *iovad);
static struct iova *to_iova(struct rb_node *node)
{ … }
void
init_iova_domain(struct iova_domain *iovad, unsigned long granule,
unsigned long start_pfn)
{ … }
EXPORT_SYMBOL_GPL(…);
static struct rb_node *
__get_cached_rbnode(struct iova_domain *iovad, unsigned long limit_pfn)
{ … }
static void
__cached_rbnode_insert_update(struct iova_domain *iovad, struct iova *new)
{ … }
static void
__cached_rbnode_delete_update(struct iova_domain *iovad, struct iova *free)
{ … }
static struct rb_node *iova_find_limit(struct iova_domain *iovad, unsigned long limit_pfn)
{ … }
static void
iova_insert_rbtree(struct rb_root *root, struct iova *iova,
struct rb_node *start)
{ … }
static int __alloc_and_insert_iova_range(struct iova_domain *iovad,
unsigned long size, unsigned long limit_pfn,
struct iova *new, bool size_aligned)
{ … }
static struct kmem_cache *iova_cache;
static unsigned int iova_cache_users;
static DEFINE_MUTEX(iova_cache_mutex);
static struct iova *alloc_iova_mem(void)
{ … }
static void free_iova_mem(struct iova *iova)
{ … }
struct iova *
alloc_iova(struct iova_domain *iovad, unsigned long size,
unsigned long limit_pfn,
bool size_aligned)
{ … }
EXPORT_SYMBOL_GPL(…);
static struct iova *
private_find_iova(struct iova_domain *iovad, unsigned long pfn)
{ … }
static void remove_iova(struct iova_domain *iovad, struct iova *iova)
{ … }
struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn)
{ … }
EXPORT_SYMBOL_GPL(…);
void
__free_iova(struct iova_domain *iovad, struct iova *iova)
{ … }
EXPORT_SYMBOL_GPL(…);
void
free_iova(struct iova_domain *iovad, unsigned long pfn)
{ … }
EXPORT_SYMBOL_GPL(…);
unsigned long
alloc_iova_fast(struct iova_domain *iovad, unsigned long size,
unsigned long limit_pfn, bool flush_rcache)
{ … }
EXPORT_SYMBOL_GPL(…);
void
free_iova_fast(struct iova_domain *iovad, unsigned long pfn, unsigned long size)
{ … }
EXPORT_SYMBOL_GPL(…);
static void iova_domain_free_rcaches(struct iova_domain *iovad)
{ … }
void put_iova_domain(struct iova_domain *iovad)
{ … }
EXPORT_SYMBOL_GPL(…);
static int
__is_range_overlap(struct rb_node *node,
unsigned long pfn_lo, unsigned long pfn_hi)
{ … }
static inline struct iova *
alloc_and_init_iova(unsigned long pfn_lo, unsigned long pfn_hi)
{ … }
static struct iova *
__insert_new_range(struct iova_domain *iovad,
unsigned long pfn_lo, unsigned long pfn_hi)
{ … }
static void
__adjust_overlap_range(struct iova *iova,
unsigned long *pfn_lo, unsigned long *pfn_hi)
{ … }
struct iova *
reserve_iova(struct iova_domain *iovad,
unsigned long pfn_lo, unsigned long pfn_hi)
{ … }
EXPORT_SYMBOL_GPL(…);
#define IOVA_MAG_SIZE …
#define IOVA_DEPOT_DELAY …
struct iova_magazine { … };
static_assert(…);
struct iova_cpu_rcache { … };
struct iova_rcache { … };
static struct kmem_cache *iova_magazine_cache;
unsigned long iova_rcache_range(void)
{ … }
static struct iova_magazine *iova_magazine_alloc(gfp_t flags)
{ … }
static void iova_magazine_free(struct iova_magazine *mag)
{ … }
static void
iova_magazine_free_pfns(struct iova_magazine *mag, struct iova_domain *iovad)
{ … }
static bool iova_magazine_full(struct iova_magazine *mag)
{ … }
static bool iova_magazine_empty(struct iova_magazine *mag)
{ … }
static unsigned long iova_magazine_pop(struct iova_magazine *mag,
unsigned long limit_pfn)
{ … }
static void iova_magazine_push(struct iova_magazine *mag, unsigned long pfn)
{ … }
static struct iova_magazine *iova_depot_pop(struct iova_rcache *rcache)
{ … }
static void iova_depot_push(struct iova_rcache *rcache, struct iova_magazine *mag)
{ … }
static void iova_depot_work_func(struct work_struct *work)
{ … }
int iova_domain_init_rcaches(struct iova_domain *iovad)
{ … }
EXPORT_SYMBOL_GPL(…);
static bool __iova_rcache_insert(struct iova_domain *iovad,
struct iova_rcache *rcache,
unsigned long iova_pfn)
{ … }
static bool iova_rcache_insert(struct iova_domain *iovad, unsigned long pfn,
unsigned long size)
{ … }
static unsigned long __iova_rcache_get(struct iova_rcache *rcache,
unsigned long limit_pfn)
{ … }
static unsigned long iova_rcache_get(struct iova_domain *iovad,
unsigned long size,
unsigned long limit_pfn)
{ … }
static void free_iova_rcaches(struct iova_domain *iovad)
{ … }
static void free_cpu_cached_iovas(unsigned int cpu, struct iova_domain *iovad)
{ … }
static void free_global_cached_iovas(struct iova_domain *iovad)
{ … }
static int iova_cpuhp_dead(unsigned int cpu, struct hlist_node *node)
{ … }
int iova_cache_get(void)
{ … }
EXPORT_SYMBOL_GPL(…);
void iova_cache_put(void)
{ … }
EXPORT_SYMBOL_GPL(…);
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;