/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2013 EMC Corp.4* Copyright (c) 2011 Jeffrey Roberson <[email protected]>5* Copyright (c) 2008 Mayur Shardul <[email protected]>6* All rights reserved.7*8* Redistribution and use in source and binary forms, with or without9* modification, are permitted provided that the following conditions10* are met:11* 1. Redistributions of source code must retain the above copyright12* notice, this list of conditions and the following disclaimer.13* 2. Redistributions in binary form must reproduce the above copyright14* notice, this list of conditions and the following disclaimer in the15* documentation and/or other materials provided with the distribution.16*17* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND18* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE19* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE20* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE21* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL22* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS23* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)24* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT25* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY26* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF27* SUCH DAMAGE.28*29*/3031/*32* Path-compressed radix trie implementation.33* The following code is not generalized into a general purpose library34* because there are way too many parameters embedded that should really35* be decided by the library consumers. At the same time, consumers36* of this code must achieve highest possible performance.37*38* The implementation takes into account the following rationale:39* - Size of the nodes should be as small as possible but still big enough40* to avoid a large maximum depth for the trie. This is a balance41* between the necessity to not wire too much physical memory for the nodes42* and the necessity to avoid too much cache pollution during the trie43* operations.44* - There is not a huge bias toward the number of lookup operations over45* the number of insert and remove operations. This basically implies46* that optimizations supposedly helping one operation but hurting the47* other might be carefully evaluated.48* - On average not many nodes are expected to be fully populated, hence49* level compression may just complicate things.50*/5152#include <sys/cdefs.h>53#include "opt_ddb.h"5455#include <sys/param.h>56#include <sys/systm.h>57#include <sys/kernel.h>58#include <sys/libkern.h>59#include <sys/pctrie.h>60#include <sys/proc.h>61#include <sys/vmmeter.h>62#include <sys/smr.h>63#include <sys/smr_types.h>6465#include <vm/uma.h>66#include <vm/vm.h>67#include <vm/vm_radix.h>6869static uma_zone_t vm_radix_node_zone;70smr_t vm_radix_smr;7172void *73vm_radix_node_alloc(struct pctrie *ptree)74{75return (uma_zalloc_smr(vm_radix_node_zone, M_NOWAIT));76}7778void79vm_radix_node_free(struct pctrie *ptree, void *node)80{81uma_zfree_smr(vm_radix_node_zone, node);82}8384#ifndef UMA_USE_DMAP85void vm_radix_reserve_kva(void);86/*87* Reserve the KVA necessary to satisfy the node allocation.88* This is mandatory in architectures not supporting direct89* mapping as they will need otherwise to carve into the kernel maps for90* every node allocation, resulting into deadlocks for consumers already91* working with kernel maps.92*/93void94vm_radix_reserve_kva(void)95{9697/*98* Calculate the number of reserved nodes, discounting the pages that99* are needed to store them.100*/101if (!uma_zone_reserve_kva(vm_radix_node_zone,102((vm_paddr_t)vm_cnt.v_page_count * PAGE_SIZE) / (PAGE_SIZE +103pctrie_node_size())))104panic("%s: unable to reserve KVA", __func__);105}106#endif107108/*109* Initialize the UMA slab zone.110*/111void112vm_radix_zinit(void)113{114115vm_radix_node_zone = uma_zcreate("RADIX NODE", pctrie_node_size(),116NULL, NULL, pctrie_zone_init, NULL,117PCTRIE_PAD, UMA_ZONE_VM | UMA_ZONE_SMR);118vm_radix_smr = uma_zone_get_smr(vm_radix_node_zone);119}120121void122vm_radix_wait(void)123{124uma_zwait(vm_radix_node_zone);125}126127128