138061Smsmith/* 238061Smsmith * Copyright (c) 2016 Citrix Systems Inc. 338061Smsmith * 438061Smsmith * This program is free software; you can redistribute it and/or 538061Smsmith * modify it under the terms of the GNU General Public License version 2 638061Smsmith * as published by the Free Softare Foundation; or, when distributed 738061Smsmith * separately from the Linux kernel or incorporated into other 838061Smsmith * software packages, subject to the following license: 938061Smsmith * 1038061Smsmith * Permission is hereby granted, free of charge, to any person obtaining a copy 1138061Smsmith * of this source file (the "Software"), to deal in the Software without 1238061Smsmith * restriction, including without limitation the rights to use, copy, modify, 1338061Smsmith * merge, publish, distribute, sublicense, and/or sell copies of the Software, 1438061Smsmith * and to permit persons to whom the Software is furnished to do so, subject to 1538061Smsmith * the following conditions: 1638061Smsmith * 1738061Smsmith * The above copyright notice and this permission notice shall be included in 1838061Smsmith * all copies or substantial portions of the Software. 1938061Smsmith * 2038061Smsmith * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2138061Smsmith * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2238061Smsmith * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2338061Smsmith * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2438061Smsmith * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2538061Smsmith * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2638061Smsmith * IN THE SOFTWARE. 2738061Smsmith */ 2838061Smsmith 29119418Sobrien#define XEN_NETIF_DEFINE_TOEPLITZ 30119418Sobrien 31119418Sobrien#include "common.h" 3238061Smsmith#include <linux/vmalloc.h> 3338061Smsmith#include <linux/rculist.h> 3438061Smsmith 3538061Smsmithstatic void xenvif_add_hash(struct xenvif *vif, const u8 *tag, 3638061Smsmith unsigned int len, u32 val) 3738061Smsmith{ 3838061Smsmith struct xenvif_hash_cache_entry *new, *entry, *oldest; 3938061Smsmith unsigned long flags; 40108470Sschweikh bool found; 4138061Smsmith 4238061Smsmith new = kmalloc(sizeof(*entry), GFP_ATOMIC); 4338061Smsmith if (!new) 4438061Smsmith return; 4538061Smsmith 4638061Smsmith memcpy(new->tag, tag, len); 4738061Smsmith new->len = len; 4838061Smsmith new->val = val; 4938061Smsmith 5038061Smsmith spin_lock_irqsave(&vif->hash.cache.lock, flags); 5138061Smsmith 5238061Smsmith found = false; 5338061Smsmith oldest = NULL; 5438061Smsmith list_for_each_entry_rcu(entry, &vif->hash.cache.list, link, 5538061Smsmith lockdep_is_held(&vif->hash.cache.lock)) { 5638061Smsmith /* Make sure we don't add duplicate entries */ 5738061Smsmith if (entry->len == len && 5838061Smsmith memcmp(entry->tag, tag, len) == 0) 5938061Smsmith found = true; 6038061Smsmith if (!oldest || entry->seq < oldest->seq) 6138061Smsmith oldest = entry; 6238061Smsmith } 6338061Smsmith 6438061Smsmith if (!found) { 6538061Smsmith new->seq = atomic_inc_return(&vif->hash.cache.seq); 6638061Smsmith list_add_rcu(&new->link, &vif->hash.cache.list); 6738061Smsmith 6838061Smsmith if (++vif->hash.cache.count > xenvif_hash_cache_size) { 6938061Smsmith list_del_rcu(&oldest->link); 7038061Smsmith vif->hash.cache.count--; 7138061Smsmith kfree_rcu(oldest, rcu); 7238061Smsmith } 7338061Smsmith } 7438061Smsmith 7538061Smsmith spin_unlock_irqrestore(&vif->hash.cache.lock, flags); 7638061Smsmith 7738061Smsmith if (found) 7838061Smsmith kfree(new); 7938061Smsmith} 8038061Smsmith 8138061Smsmithstatic u32 xenvif_new_hash(struct xenvif *vif, const u8 *data, 8238061Smsmith unsigned int len) 8355939Snsouch{ 8455939Snsouch u32 val; 8538061Smsmith 8638061Smsmith val = xen_netif_toeplitz_hash(vif->hash.key, 8755939Snsouch sizeof(vif->hash.key), 8855939Snsouch data, len); 8938061Smsmith 9038061Smsmith if (xenvif_hash_cache_size != 0) 9138061Smsmith xenvif_add_hash(vif, data, len, val); 9238061Smsmith 9338061Smsmith return val; 9438061Smsmith} 9555939Snsouch 9655939Snsouchstatic void xenvif_flush_hash(struct xenvif *vif) 9755939Snsouch{ 9855939Snsouch struct xenvif_hash_cache_entry *entry; 9938061Smsmith unsigned long flags; 10038061Smsmith 10138061Smsmith if (xenvif_hash_cache_size == 0) 10238061Smsmith return; 10338061Smsmith 10438061Smsmith spin_lock_irqsave(&vif->hash.cache.lock, flags); 10538061Smsmith 10638061Smsmith list_for_each_entry_rcu(entry, &vif->hash.cache.list, link, 10738061Smsmith lockdep_is_held(&vif->hash.cache.lock)) { 10838061Smsmith list_del_rcu(&entry->link); 10955939Snsouch vif->hash.cache.count--; 11055939Snsouch kfree_rcu(entry, rcu); 11138061Smsmith } 11238061Smsmith 11338061Smsmith spin_unlock_irqrestore(&vif->hash.cache.lock, flags); 11438061Smsmith} 11538061Smsmith 11638061Smsmithstatic u32 xenvif_find_hash(struct xenvif *vif, const u8 *data, 11738061Smsmith unsigned int len) 11838061Smsmith{ 11938061Smsmith struct xenvif_hash_cache_entry *entry; 12038061Smsmith u32 val; 12138061Smsmith bool found; 12238061Smsmith 12338061Smsmith if (len >= XEN_NETBK_HASH_TAG_SIZE) 12438061Smsmith return 0; 12538061Smsmith 12638061Smsmith if (xenvif_hash_cache_size == 0) 12738061Smsmith return xenvif_new_hash(vif, data, len); 12838061Smsmith 12938061Smsmith rcu_read_lock(); 13038061Smsmith 13138061Smsmith found = false; 13238061Smsmith 13338061Smsmith list_for_each_entry_rcu(entry, &vif->hash.cache.list, link) { 13438061Smsmith if (entry->len == len && 13538061Smsmith memcmp(entry->tag, data, len) == 0) { 13638061Smsmith val = entry->val; 13738061Smsmith entry->seq = atomic_inc_return(&vif->hash.cache.seq); 13838061Smsmith found = true; 13938061Smsmith break; 14038061Smsmith } 14143433Snsouch } 14243433Snsouch 14338061Smsmith rcu_read_unlock(); 14443433Snsouch 14543433Snsouch if (!found) 14638061Smsmith val = xenvif_new_hash(vif, data, len); 14738061Smsmith 14855939Snsouch return val; 14938061Smsmith} 15038061Smsmith 15138061Smsmithvoid xenvif_set_skb_hash(struct xenvif *vif, struct sk_buff *skb) 15255939Snsouch{ 15355939Snsouch struct flow_keys flow; 15438061Smsmith u32 hash = 0; 15538061Smsmith enum pkt_hash_types type = PKT_HASH_TYPE_NONE; 15638061Smsmith u32 flags = vif->hash.flags; 15738061Smsmith bool has_tcp_hdr; 15838061Smsmith 15938061Smsmith /* Quick rejection test: If the network protocol doesn't 16038061Smsmith * correspond to any enabled hash type then there's no point 16138061Smsmith * in parsing the packet header. 16238061Smsmith */ 16338061Smsmith switch (skb->protocol) { 16438061Smsmith case htons(ETH_P_IP): 16538061Smsmith if (flags & (XEN_NETIF_CTRL_HASH_TYPE_IPV4_TCP | 16638061Smsmith XEN_NETIF_CTRL_HASH_TYPE_IPV4)) 16738061Smsmith break; 16838061Smsmith 16938061Smsmith goto done; 17038061Smsmith 17138061Smsmith case htons(ETH_P_IPV6): 17255939Snsouch if (flags & (XEN_NETIF_CTRL_HASH_TYPE_IPV6_TCP | 17338061Smsmith XEN_NETIF_CTRL_HASH_TYPE_IPV6)) 17455939Snsouch break; 17555939Snsouch 17655939Snsouch goto done; 17755939Snsouch 17855939Snsouch default: 17955939Snsouch goto done; 18038061Smsmith } 18155939Snsouch 18255939Snsouch memset(&flow, 0, sizeof(flow)); 18356455Speter if (!skb_flow_dissect_flow_keys(skb, &flow, 0)) 18456455Speter goto done; 18556455Speter 18655939Snsouch has_tcp_hdr = (flow.basic.ip_proto == IPPROTO_TCP) && 18794154Sticso !(flow.control.flags & FLOW_DIS_IS_FRAGMENT); 18856455Speter 18938061Smsmith switch (skb->protocol) { 19038061Smsmith case htons(ETH_P_IP): 19138061Smsmith if (has_tcp_hdr && 19255939Snsouch (flags & XEN_NETIF_CTRL_HASH_TYPE_IPV4_TCP)) { 19355939Snsouch u8 data[12]; 19438061Smsmith 19555939Snsouch memcpy(&data[0], &flow.addrs.v4addrs.src, 4); 19655939Snsouch memcpy(&data[4], &flow.addrs.v4addrs.dst, 4); 19756618Sdfr memcpy(&data[8], &flow.ports.src, 2); 19857177Speter memcpy(&data[10], &flow.ports.dst, 2); 19938061Smsmith 20055939Snsouch hash = xenvif_find_hash(vif, data, sizeof(data)); 20155939Snsouch type = PKT_HASH_TYPE_L4; 20255939Snsouch } else if (flags & XEN_NETIF_CTRL_HASH_TYPE_IPV4) { 20355939Snsouch u8 data[8]; 20455939Snsouch 20555939Snsouch memcpy(&data[0], &flow.addrs.v4addrs.src, 4); 20638061Smsmith memcpy(&data[4], &flow.addrs.v4addrs.dst, 4); 20755939Snsouch 20855939Snsouch hash = xenvif_find_hash(vif, data, sizeof(data)); 20955939Snsouch type = PKT_HASH_TYPE_L3; 21043989Snsouch } 21138061Smsmith 21255939Snsouch break; 21355939Snsouch 21455939Snsouch case htons(ETH_P_IPV6): 21555939Snsouch if (has_tcp_hdr && 21655939Snsouch (flags & XEN_NETIF_CTRL_HASH_TYPE_IPV6_TCP)) { 21755939Snsouch u8 data[36]; 21838061Smsmith 21938061Smsmith memcpy(&data[0], &flow.addrs.v6addrs.src, 16); 22038061Smsmith memcpy(&data[16], &flow.addrs.v6addrs.dst, 16); 22138061Smsmith memcpy(&data[32], &flow.ports.src, 2); 22238061Smsmith memcpy(&data[34], &flow.ports.dst, 2); 22338061Smsmith 22455939Snsouch hash = xenvif_find_hash(vif, data, sizeof(data)); 22538061Smsmith type = PKT_HASH_TYPE_L4; 22655939Snsouch } else if (flags & XEN_NETIF_CTRL_HASH_TYPE_IPV6) { 22738061Smsmith u8 data[32]; 22838061Smsmith 22938061Smsmith memcpy(&data[0], &flow.addrs.v6addrs.src, 16); 23055939Snsouch memcpy(&data[16], &flow.addrs.v6addrs.dst, 16); 23138061Smsmith 23255939Snsouch hash = xenvif_find_hash(vif, data, sizeof(data)); 23355939Snsouch type = PKT_HASH_TYPE_L3; 23438061Smsmith } 23555939Snsouch 236121816Sbrooks break; 23738061Smsmith } 23838061Smsmith 23938061Smsmithdone: 24038061Smsmith if (type == PKT_HASH_TYPE_NONE) 24138061Smsmith skb_clear_hash(skb); 24238061Smsmith else 24338061Smsmith __skb_set_sw_hash(skb, hash, type == PKT_HASH_TYPE_L4); 24438061Smsmith} 24538061Smsmith 24638061Smsmithu32 xenvif_set_hash_alg(struct xenvif *vif, u32 alg) 24743773Sdes{ 24838061Smsmith switch (alg) { 24955939Snsouch case XEN_NETIF_CTRL_HASH_ALGORITHM_NONE: 25038061Smsmith case XEN_NETIF_CTRL_HASH_ALGORITHM_TOEPLITZ: 25138061Smsmith break; 25238061Smsmith 25338061Smsmith default: 25438061Smsmith return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER; 25538061Smsmith } 25638061Smsmith 25738061Smsmith vif->hash.alg = alg; 25838061Smsmith 25938061Smsmith return XEN_NETIF_CTRL_STATUS_SUCCESS; 26038061Smsmith} 26138061Smsmith 26238061Smsmithu32 xenvif_get_hash_flags(struct xenvif *vif, u32 *flags) 26338061Smsmith{ 26438061Smsmith if (vif->hash.alg == XEN_NETIF_CTRL_HASH_ALGORITHM_NONE) 26538061Smsmith return XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED; 26638061Smsmith 26738061Smsmith *flags = XEN_NETIF_CTRL_HASH_TYPE_IPV4 | 26838061Smsmith XEN_NETIF_CTRL_HASH_TYPE_IPV4_TCP | 26938061Smsmith XEN_NETIF_CTRL_HASH_TYPE_IPV6 | 27038061Smsmith XEN_NETIF_CTRL_HASH_TYPE_IPV6_TCP; 27138061Smsmith 27238061Smsmith return XEN_NETIF_CTRL_STATUS_SUCCESS; 27338061Smsmith} 27438061Smsmith 27538061Smsmithu32 xenvif_set_hash_flags(struct xenvif *vif, u32 flags) 27638061Smsmith{ 27738061Smsmith if (flags & ~(XEN_NETIF_CTRL_HASH_TYPE_IPV4 | 27838061Smsmith XEN_NETIF_CTRL_HASH_TYPE_IPV4_TCP | 27938061Smsmith XEN_NETIF_CTRL_HASH_TYPE_IPV6 | 28038061Smsmith XEN_NETIF_CTRL_HASH_TYPE_IPV6_TCP)) 28138061Smsmith return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER; 28238061Smsmith 28338061Smsmith if (vif->hash.alg == XEN_NETIF_CTRL_HASH_ALGORITHM_NONE) 28438061Smsmith return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER; 28538061Smsmith 28638061Smsmith vif->hash.flags = flags; 28738061Smsmith 28838061Smsmith return XEN_NETIF_CTRL_STATUS_SUCCESS; 28938061Smsmith} 29038061Smsmith 29138061Smsmithu32 xenvif_set_hash_key(struct xenvif *vif, u32 gref, u32 len) 29238061Smsmith{ 29338061Smsmith u8 *key = vif->hash.key; 29438061Smsmith struct gnttab_copy copy_op = { 29538061Smsmith .source.u.ref = gref, 29638061Smsmith .source.domid = vif->domid, 297121816Sbrooks .dest.u.gmfn = virt_to_gfn(key), 29855939Snsouch .dest.domid = DOMID_SELF, 29955939Snsouch .dest.offset = xen_offset_in_page(key), 30038061Smsmith .len = len, 30138061Smsmith .flags = GNTCOPY_source_gref 30238061Smsmith }; 30355939Snsouch 30438061Smsmith if (len > XEN_NETBK_MAX_HASH_KEY_SIZE) 30538061Smsmith return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER; 30638061Smsmith 30738061Smsmith if (copy_op.len != 0) { 30838061Smsmith gnttab_batch_copy(©_op, 1); 30938061Smsmith 31038061Smsmith if (copy_op.status != GNTST_okay) 31138061Smsmith return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER; 31238061Smsmith } 31338061Smsmith 31438061Smsmith /* Clear any remaining key octets */ 31538061Smsmith if (len < XEN_NETBK_MAX_HASH_KEY_SIZE) 31638061Smsmith memset(key + len, 0, XEN_NETBK_MAX_HASH_KEY_SIZE - len); 31738061Smsmith 31838061Smsmith xenvif_flush_hash(vif); 31955939Snsouch 32038061Smsmith return XEN_NETIF_CTRL_STATUS_SUCCESS; 32138061Smsmith} 32238061Smsmith 32355939Snsouchu32 xenvif_set_hash_mapping_size(struct xenvif *vif, u32 size) 32438061Smsmith{ 32538061Smsmith if (size > XEN_NETBK_MAX_HASH_MAPPING_SIZE) 32638061Smsmith return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER; 32738061Smsmith 32842443Snsouch vif->hash.size = size; 32938061Smsmith memset(vif->hash.mapping[vif->hash.mapping_sel], 0, 33038061Smsmith sizeof(u32) * size); 33155939Snsouch 33238061Smsmith return XEN_NETIF_CTRL_STATUS_SUCCESS; 33338061Smsmith} 33442443Snsouch 33542443Snsouchu32 xenvif_set_hash_mapping(struct xenvif *vif, u32 gref, u32 len, 33655939Snsouch u32 off) 33742443Snsouch{ 33838061Smsmith u32 *mapping = vif->hash.mapping[!vif->hash.mapping_sel]; 33955939Snsouch unsigned int nr = 1; 34038061Smsmith struct gnttab_copy copy_op[2] = {{ 34138061Smsmith .source.u.ref = gref, 34238061Smsmith .source.domid = vif->domid, 34338061Smsmith .dest.domid = DOMID_SELF, 344111119Simp .len = len * sizeof(*mapping), 34538061Smsmith .flags = GNTCOPY_source_gref 34655939Snsouch }}; 34738061Smsmith 34838061Smsmith if ((off + len < off) || (off + len > vif->hash.size) || 34938061Smsmith len > XEN_PAGE_SIZE / sizeof(*mapping)) 35055939Snsouch return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER; 35155939Snsouch 35255939Snsouch copy_op[0].dest.u.gmfn = virt_to_gfn(mapping + off); 35355939Snsouch copy_op[0].dest.offset = xen_offset_in_page(mapping + off); 35455939Snsouch if (copy_op[0].dest.offset + copy_op[0].len > XEN_PAGE_SIZE) { 35555939Snsouch copy_op[1] = copy_op[0]; 35655939Snsouch copy_op[1].source.offset = XEN_PAGE_SIZE - copy_op[0].dest.offset; 35755939Snsouch copy_op[1].dest.u.gmfn = virt_to_gfn(mapping + off + len); 35838061Smsmith copy_op[1].dest.offset = 0; 35938061Smsmith copy_op[1].len = copy_op[0].len - copy_op[1].source.offset; 36038061Smsmith copy_op[0].len = copy_op[1].source.offset; 36138061Smsmith nr = 2; 36238061Smsmith } 36338061Smsmith 36438061Smsmith memcpy(mapping, vif->hash.mapping[vif->hash.mapping_sel], 36538061Smsmith vif->hash.size * sizeof(*mapping)); 36638061Smsmith 36738061Smsmith if (copy_op[0].len != 0) { 36838061Smsmith gnttab_batch_copy(copy_op, nr); 36938061Smsmith 37038061Smsmith if (copy_op[0].status != GNTST_okay || 37138061Smsmith copy_op[nr - 1].status != GNTST_okay) 37238061Smsmith return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER; 37338061Smsmith } 37438061Smsmith 37538061Smsmith while (len-- != 0) 37638061Smsmith if (mapping[off++] >= vif->num_queues) 37738061Smsmith return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER; 37838061Smsmith 37938061Smsmith vif->hash.mapping_sel = !vif->hash.mapping_sel; 38038061Smsmith 38138061Smsmith return XEN_NETIF_CTRL_STATUS_SUCCESS; 38238061Smsmith} 38338061Smsmith 38438061Smsmith#ifdef CONFIG_DEBUG_FS 38538061Smsmithvoid xenvif_dump_hash_info(struct xenvif *vif, struct seq_file *m) 38638061Smsmith{ 38738061Smsmith unsigned int i; 38838061Smsmith 38938061Smsmith switch (vif->hash.alg) { 39038061Smsmith case XEN_NETIF_CTRL_HASH_ALGORITHM_TOEPLITZ: 39138061Smsmith seq_puts(m, "Hash Algorithm: TOEPLITZ\n"); 39238061Smsmith break; 39340626Smsmith 39440626Smsmith case XEN_NETIF_CTRL_HASH_ALGORITHM_NONE: 39540626Smsmith seq_puts(m, "Hash Algorithm: NONE\n"); 39640626Smsmith fallthrough; 39740626Smsmith default: 39840626Smsmith return; 39940626Smsmith } 40038061Smsmith 40138373Sbde if (vif->hash.flags) { 40238061Smsmith seq_puts(m, "\nHash Flags:\n"); 40338061Smsmith 40438061Smsmith if (vif->hash.flags & XEN_NETIF_CTRL_HASH_TYPE_IPV4) 40538061Smsmith seq_puts(m, "- IPv4\n"); 40638061Smsmith if (vif->hash.flags & XEN_NETIF_CTRL_HASH_TYPE_IPV4_TCP) 40738061Smsmith seq_puts(m, "- IPv4 + TCP\n"); 40855939Snsouch if (vif->hash.flags & XEN_NETIF_CTRL_HASH_TYPE_IPV6) 40938061Smsmith seq_puts(m, "- IPv6\n"); 41055939Snsouch if (vif->hash.flags & XEN_NETIF_CTRL_HASH_TYPE_IPV6_TCP) 41155939Snsouch seq_puts(m, "- IPv6 + TCP\n"); 41238061Smsmith } 41338061Smsmith 41438061Smsmith seq_puts(m, "\nHash Key:\n"); 41555939Snsouch 41655939Snsouch for (i = 0; i < XEN_NETBK_MAX_HASH_KEY_SIZE; ) { 41738061Smsmith unsigned int j, n; 41838061Smsmith 41938061Smsmith n = 8; 42038061Smsmith if (i + n >= XEN_NETBK_MAX_HASH_KEY_SIZE) 42138061Smsmith n = XEN_NETBK_MAX_HASH_KEY_SIZE - i; 42238061Smsmith 42338061Smsmith seq_printf(m, "[%2u - %2u]: ", i, i + n - 1); 42455939Snsouch 42538061Smsmith for (j = 0; j < n; j++, i++) 42642443Snsouch seq_printf(m, "%02x ", vif->hash.key[i]); 42738061Smsmith 42855939Snsouch seq_puts(m, "\n"); 42938061Smsmith } 43038061Smsmith 43138061Smsmith if (vif->hash.size != 0) { 43255939Snsouch const u32 *mapping = vif->hash.mapping[vif->hash.mapping_sel]; 43355939Snsouch 43438061Smsmith seq_puts(m, "\nHash Mapping:\n"); 43555939Snsouch 43638061Smsmith for (i = 0; i < vif->hash.size; ) { 43738061Smsmith unsigned int j, n; 43838061Smsmith 43955939Snsouch n = 8; 44055939Snsouch if (i + n >= vif->hash.size) 44138061Smsmith n = vif->hash.size - i; 44238061Smsmith 44338061Smsmith seq_printf(m, "[%4u - %4u]: ", i, i + n - 1); 44438061Smsmith 44538061Smsmith for (j = 0; j < n; j++, i++) 44643773Sdes seq_printf(m, "%4u ", mapping[i]); 44743773Sdes 44843773Sdes seq_puts(m, "\n"); 44943773Sdes } 45043773Sdes } 45143773Sdes} 45243773Sdes#endif /* CONFIG_DEBUG_FS */ 45343773Sdes 45443773Sdesvoid xenvif_init_hash(struct xenvif *vif) 45543773Sdes{ 45643773Sdes if (xenvif_hash_cache_size == 0) 45743773Sdes return; 45843773Sdes 45943773Sdes BUG_ON(vif->hash.cache.count); 460106937Ssam 46143773Sdes spin_lock_init(&vif->hash.cache.lock); 46243773Sdes INIT_LIST_HEAD(&vif->hash.cache.list); 46343773Sdes} 46455939Snsouch 46538061Smsmithvoid xenvif_deinit_hash(struct xenvif *vif) 46655939Snsouch{ 46755939Snsouch xenvif_flush_hash(vif); 46855939Snsouch} 46938061Smsmith