1 // SPDX-License-Identifier: GPL-2.0-only 2 // Copyright (C) 2022-2023 Isovalent, Inc. 3 digraph { 4 node [colorscheme=accent4,style=filled] # Apply colorscheme to all nodes 5 graph [splines=ortho, nodesep=1] 6 7 subgraph cluster_key { 8 label = "Key\n(locks held during operation)"; 9 rankdir = TB; 10 11 remote_lock [shape=rectangle,fillcolor=4,label="remote CPU LRU lock"] 12 hash_lock [shape=rectangle,fillcolor=3,label="hashtab lock"] 13 lru_lock [shape=rectangle,fillcolor=2,label="LRU lock"] 14 local_lock [shape=rectangle,fillcolor=1,label="local CPU LRU lock"] 15 no_lock [shape=rectangle,label="no locks held"] 16 } 17 18 begin [shape=oval,label="begin\nbpf_map_update()"] 19 20 // Nodes below with an 'fn_' prefix are roughly labeled by the C function 21 // names that initiate the corresponding logic in kernel/bpf/bpf_lru_list.c. 22 // Number suffixes and errno suffixes handle subsections of the corresponding 23 // logic in the function as of the writing of this dot. 24 25 // cf. __local_list_pop_free() / bpf_percpu_lru_pop_free() 26 local_freelist_check [shape=diamond,fillcolor=1, 27 label="Local freelist\nnode available?"]; 28 use_local_node [shape=rectangle, 29 label="Use node owned\nby this CPU"] 30 31 // cf. bpf_lru_pop_free() 32 common_lru_check [shape=diamond, 33 label="Map created with\ncommon LRU?\n(!BPF_F_NO_COMMON_LRU)"]; 34 35 fn_bpf_lru_list_pop_free_to_local [shape=rectangle,fillcolor=2, 36 label="Flush local pending, 37 Rotate Global list, move 38 LOCAL_FREE_TARGET 39 from global -> local"] 40 // Also corresponds to: 41 // fn__local_list_flush() 42 // fn_bpf_lru_list_rotate() 43 fn___bpf_lru_node_move_to_free[shape=diamond,fillcolor=2, 44 label="Able to free\nLOCAL_FREE_TARGET\nnodes?"] 45 46 fn___bpf_lru_list_shrink_inactive [shape=rectangle,fillcolor=3, 47 label="Shrink inactive list 48 up to remaining 49 LOCAL_FREE_TARGET 50 (global LRU -> local)"] 51 fn___bpf_lru_list_shrink [shape=diamond,fillcolor=2, 52 label="> 0 entries in\nlocal free list?"] 53 fn___bpf_lru_list_shrink2 [shape=rectangle,fillcolor=2, 54 label="Steal one node from 55 inactive, or if empty, 56 from active global list"] 57 fn___bpf_lru_list_shrink3 [shape=rectangle,fillcolor=3, 58 label="Try to remove\nnode from hashtab"] 59 60 local_freelist_check2 [shape=diamond,label="Htab removal\nsuccessful?"] 61 common_lru_check2 [shape=diamond, 62 label="Map created with\ncommon LRU?\n(!BPF_F_NO_COMMON_LRU)"]; 63 64 subgraph cluster_remote_lock { 65 label = "Iterate through CPUs\n(start from current)"; 66 style = dashed; 67 rankdir=LR; 68 69 local_freelist_check5 [shape=diamond,fillcolor=4, 70 label="Steal a node from\nper-cpu freelist?"] 71 local_freelist_check6 [shape=rectangle,fillcolor=4, 72 label="Steal a node from 73 (1) Unreferenced pending, or 74 (2) Any pending node"] 75 local_freelist_check7 [shape=rectangle,fillcolor=3, 76 label="Try to remove\nnode from hashtab"] 77 fn_htab_lru_map_update_elem [shape=diamond, 78 label="Stole node\nfrom remote\nCPU?"] 79 fn_htab_lru_map_update_elem2 [shape=diamond,label="Iterated\nall CPUs?"] 80 // Also corresponds to: 81 // use_local_node() 82 // fn__local_list_pop_pending() 83 } 84 85 fn_bpf_lru_list_pop_free_to_local2 [shape=rectangle, 86 label="Use node that was\nnot recently referenced"] 87 local_freelist_check4 [shape=rectangle, 88 label="Use node that was\nactively referenced\nin global list"] 89 fn_htab_lru_map_update_elem_ENOMEM [shape=oval,label="return -ENOMEM"] 90 fn_htab_lru_map_update_elem3 [shape=rectangle, 91 label="Use node that was\nactively referenced\nin (another?) CPU's cache"] 92 fn_htab_lru_map_update_elem4 [shape=rectangle,fillcolor=3, 93 label="Update hashmap\nwith new element"] 94 fn_htab_lru_map_update_elem5 [shape=oval,label="return 0"] 95 fn_htab_lru_map_update_elem_EBUSY [shape=oval,label="return -EBUSY"] 96 fn_htab_lru_map_update_elem_EEXIST [shape=oval,label="return -EEXIST"] 97 fn_htab_lru_map_update_elem_ENOENT [shape=oval,label="return -ENOENT"] 98 99 begin -> local_freelist_check 100 local_freelist_check -> use_local_node [xlabel="Y"] 101 local_freelist_check -> common_lru_check [xlabel="N"] 102 common_lru_check -> fn_bpf_lru_list_pop_free_to_local [xlabel="Y"] 103 common_lru_check -> fn___bpf_lru_list_shrink_inactive [xlabel="N"] 104 fn_bpf_lru_list_pop_free_to_local -> fn___bpf_lru_node_move_to_free 105 fn___bpf_lru_node_move_to_free -> 106 fn_bpf_lru_list_pop_free_to_local2 [xlabel="Y"] 107 fn___bpf_lru_node_move_to_free -> 108 fn___bpf_lru_list_shrink_inactive [xlabel="N"] 109 fn___bpf_lru_list_shrink_inactive -> fn___bpf_lru_list_shrink 110 fn___bpf_lru_list_shrink -> fn_bpf_lru_list_pop_free_to_local2 [xlabel = "Y"] 111 fn___bpf_lru_list_shrink -> fn___bpf_lru_list_shrink2 [xlabel="N"] 112 fn___bpf_lru_list_shrink2 -> fn___bpf_lru_list_shrink3 113 fn___bpf_lru_list_shrink3 -> local_freelist_check2 114 local_freelist_check2 -> local_freelist_check4 [xlabel = "Y"] 115 local_freelist_check2 -> common_lru_check2 [xlabel = "N"] 116 common_lru_check2 -> local_freelist_check5 [xlabel = "Y"] 117 common_lru_check2 -> fn_htab_lru_map_update_elem_ENOMEM [xlabel = "N"] 118 local_freelist_check5 -> fn_htab_lru_map_update_elem [xlabel = "Y"] 119 local_freelist_check5 -> local_freelist_check6 [xlabel = "N"] 120 local_freelist_check6 -> local_freelist_check7 121 local_freelist_check7 -> fn_htab_lru_map_update_elem 122 123 fn_htab_lru_map_update_elem -> fn_htab_lru_map_update_elem3 [xlabel = "Y"] 124 fn_htab_lru_map_update_elem -> fn_htab_lru_map_update_elem2 [xlabel = "N"] 125 fn_htab_lru_map_update_elem2 -> 126 fn_htab_lru_map_update_elem_ENOMEM [xlabel = "Y"] 127 fn_htab_lru_map_update_elem2 -> local_freelist_check5 [xlabel = "N"] 128 fn_htab_lru_map_update_elem3 -> fn_htab_lru_map_update_elem4 129 130 use_local_node -> fn_htab_lru_map_update_elem4 131 fn_bpf_lru_list_pop_free_to_local2 -> fn_htab_lru_map_update_elem4 132 local_freelist_check4 -> fn_htab_lru_map_update_elem4 133 134 fn_htab_lru_map_update_elem4 -> fn_htab_lru_map_update_elem5 [headlabel="Success"] 135 fn_htab_lru_map_update_elem4 -> 136 fn_htab_lru_map_update_elem_EBUSY [xlabel="Hashtab lock failed"] 137 fn_htab_lru_map_update_elem4 -> 138 fn_htab_lru_map_update_elem_EEXIST [xlabel="BPF_EXIST set and\nkey already exists"] 139 fn_htab_lru_map_update_elem4 -> 140 fn_htab_lru_map_update_elem_ENOENT [headlabel="BPF_NOEXIST set\nand no such entry"] 141 142 // Create invisible pad nodes to line up various nodes 143 pad0 [style=invis] 144 pad1 [style=invis] 145 pad2 [style=invis] 146 pad3 [style=invis] 147 pad4 [style=invis] 148 149 // Line up the key with the top of the graph 150 no_lock -> local_lock [style=invis] 151 local_lock -> lru_lock [style=invis] 152 lru_lock -> hash_lock [style=invis] 153 hash_lock -> remote_lock [style=invis] 154 remote_lock -> local_freelist_check5 [style=invis] 155 remote_lock -> fn___bpf_lru_list_shrink [style=invis] 156 157 // Line up return code nodes at the bottom of the graph 158 fn_htab_lru_map_update_elem -> pad0 [style=invis] 159 pad0 -> pad1 [style=invis] 160 pad1 -> pad2 [style=invis] 161 //pad2-> fn_htab_lru_map_update_elem_ENOMEM [style=invis] 162 fn_htab_lru_map_update_elem4 -> pad3 [style=invis] 163 pad3 -> fn_htab_lru_map_update_elem5 [style=invis] 164 pad3 -> fn_htab_lru_map_update_elem_EBUSY [style=invis] 165 pad3 -> fn_htab_lru_map_update_elem_EEXIST [style=invis] 166 pad3 -> fn_htab_lru_map_update_elem_ENOENT [style=invis] 167 168 // Reduce diagram width by forcing some nodes to appear above others 169 local_freelist_check4 -> fn_htab_lru_map_update_elem3 [style=invis] 170 common_lru_check2 -> pad4 [style=invis] 171 pad4 -> local_freelist_check5 [style=invis] 172 }
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.