/* SPDX-License-Identifier: GPL-2.0 */ #if 1 #include #include #include #include #include #include #include #include #include #include #include #include #include #endif struct maple_tree mt; struct va { u64 addr; u64 range; }; static int va_store(struct va *va) { void *entry = NULL; u64 addr = va->addr; u64 range = va->range; u64 last = addr + range - 1; MA_STATE(mas, &mt, addr, addr); int ret; mas_lock(&mas); if ((entry = mas_walk(&mas))) { pr_err("addr=%llx, range=%llx, last=%llx, mas.index=%lx, mas.last=%lx, entry=%px - exists\n", addr, range, last, mas.index, mas.last, entry); ret = -EEXIST; goto err_unlock; } if (mas.last < last) { pr_err("addr=%llx, range=%llx, last=%llx, mas.index=%lx, mas.last%lx, va=%px - not enough space\n", addr, range, last, mas.index, mas.last, va); ret = -EEXIST; goto err_unlock; } mas.last = last; ret = mas_store_gfp(&mas, &va, GFP_KERNEL); if (ret) { pr_err("mas_store_gfp() failed\n"); goto err_unlock; } mas_unlock(&mas); pr_info("addr=%llx, range=%llx, last=%llx, mas.index=%lx, mas.last=%lx, va=%px - insert\n", addr, range, last, mas.index, mas.last, va); return 0; err_unlock: mas_unlock(&mas); return ret; } static int __init maple_init(void) { struct va kernel_node = { .addr = 0xc0000, .range = 0x40000 }; struct va node = { .addr = 0x0, .range = 0xc0000 }; mt_init(&mt); va_store(&kernel_node); va_store(&node); return 0; } static void __exit maple_exit(void) { mtree_lock(&mt); __mt_destroy(&mt); mtree_unlock(&mt); } module_init(maple_init); module_exit(maple_exit); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Danilo Krummrich"); MODULE_DESCRIPTION("Maple Tree example."); MODULE_VERSION("0.1");