rx.c (10a558374f3751cf4eb55143008975641dfc2cf4) | rx.c (3af0f34290f6192756ee1d9c2d5fe27222267035) |
---|---|
1/**************************************************************************** 2 * Driver for Solarflare network controllers and boards 3 * Copyright 2005-2006 Fen Systems Ltd. 4 * Copyright 2005-2013 Solarflare Communications Inc. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 as published 8 * by the Free Software Foundation, incorporated herein by reference. --- 813 unchanged lines hidden (view full) --- 822 823 824module_param(rx_refill_threshold, uint, 0444); 825MODULE_PARM_DESC(rx_refill_threshold, 826 "RX descriptor ring refill threshold (%)"); 827 828#ifdef CONFIG_RFS_ACCEL 829 | 1/**************************************************************************** 2 * Driver for Solarflare network controllers and boards 3 * Copyright 2005-2006 Fen Systems Ltd. 4 * Copyright 2005-2013 Solarflare Communications Inc. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 as published 8 * by the Free Software Foundation, incorporated herein by reference. --- 813 unchanged lines hidden (view full) --- 822 823 824module_param(rx_refill_threshold, uint, 0444); 825MODULE_PARM_DESC(rx_refill_threshold, 826 "RX descriptor ring refill threshold (%)"); 827 828#ifdef CONFIG_RFS_ACCEL 829 |
830/** 831 * struct efx_async_filter_insertion - Request to asynchronously insert a filter 832 * @net_dev: Reference to the netdevice 833 * @spec: The filter to insert 834 * @work: Workitem for this request 835 * @rxq_index: Identifies the channel for which this request was made 836 * @flow_id: Identifies the kernel-side flow for which this request was made 837 */ 838struct efx_async_filter_insertion { 839 struct net_device *net_dev; 840 struct efx_filter_spec spec; 841 struct work_struct work; 842 u16 rxq_index; 843 u32 flow_id; 844}; 845 846static void efx_filter_rfs_work(struct work_struct *data) 847{ 848 struct efx_async_filter_insertion *req = container_of(data, struct efx_async_filter_insertion, 849 work); 850 struct efx_nic *efx = netdev_priv(req->net_dev); 851 struct efx_channel *channel = efx_get_channel(efx, req->rxq_index); 852 int rc; 853 854 rc = efx->type->filter_insert(efx, &req->spec, false); 855 if (rc >= 0) { 856 /* Remember this so we can check whether to expire the filter 857 * later. 858 */ 859 mutex_lock(&efx->rps_mutex); 860 channel->rps_flow_id[rc] = req->flow_id; 861 ++channel->rfs_filters_added; 862 mutex_unlock(&efx->rps_mutex); 863 864 if (req->spec.ether_type == htons(ETH_P_IP)) 865 netif_info(efx, rx_status, efx->net_dev, 866 "steering %s %pI4:%u:%pI4:%u to queue %u [flow %u filter %d]\n", 867 (req->spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP", 868 req->spec.rem_host, ntohs(req->spec.rem_port), 869 req->spec.loc_host, ntohs(req->spec.loc_port), 870 req->rxq_index, req->flow_id, rc); 871 else 872 netif_info(efx, rx_status, efx->net_dev, 873 "steering %s [%pI6]:%u:[%pI6]:%u to queue %u [flow %u filter %d]\n", 874 (req->spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP", 875 req->spec.rem_host, ntohs(req->spec.rem_port), 876 req->spec.loc_host, ntohs(req->spec.loc_port), 877 req->rxq_index, req->flow_id, rc); 878 } 879 880 /* Release references */ 881 dev_put(req->net_dev); 882 kfree(req); 883} 884 |
|
830int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, 831 u16 rxq_index, u32 flow_id) 832{ 833 struct efx_nic *efx = netdev_priv(net_dev); | 885int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, 886 u16 rxq_index, u32 flow_id) 887{ 888 struct efx_nic *efx = netdev_priv(net_dev); |
834 struct efx_channel *channel; 835 struct efx_filter_spec spec; | 889 struct efx_async_filter_insertion *req; |
836 struct flow_keys fk; | 890 struct flow_keys fk; |
837 int rc; | |
838 839 if (flow_id == RPS_FLOW_ID_INVALID) 840 return -EINVAL; 841 842 if (!skb_flow_dissect_flow_keys(skb, &fk, 0)) 843 return -EPROTONOSUPPORT; 844 845 if (fk.basic.n_proto != htons(ETH_P_IP) && fk.basic.n_proto != htons(ETH_P_IPV6)) 846 return -EPROTONOSUPPORT; 847 if (fk.control.flags & FLOW_DIS_IS_FRAGMENT) 848 return -EPROTONOSUPPORT; 849 | 891 892 if (flow_id == RPS_FLOW_ID_INVALID) 893 return -EINVAL; 894 895 if (!skb_flow_dissect_flow_keys(skb, &fk, 0)) 896 return -EPROTONOSUPPORT; 897 898 if (fk.basic.n_proto != htons(ETH_P_IP) && fk.basic.n_proto != htons(ETH_P_IPV6)) 899 return -EPROTONOSUPPORT; 900 if (fk.control.flags & FLOW_DIS_IS_FRAGMENT) 901 return -EPROTONOSUPPORT; 902 |
850 efx_filter_init_rx(&spec, EFX_FILTER_PRI_HINT, | 903 req = kmalloc(sizeof(*req), GFP_ATOMIC); 904 if (!req) 905 return -ENOMEM; 906 907 efx_filter_init_rx(&req->spec, EFX_FILTER_PRI_HINT, |
851 efx->rx_scatter ? EFX_FILTER_FLAG_RX_SCATTER : 0, 852 rxq_index); | 908 efx->rx_scatter ? EFX_FILTER_FLAG_RX_SCATTER : 0, 909 rxq_index); |
853 spec.match_flags = | 910 req->spec.match_flags = |
854 EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO | 855 EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT | 856 EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT; | 911 EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO | 912 EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT | 913 EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT; |
857 spec.ether_type = fk.basic.n_proto; 858 spec.ip_proto = fk.basic.ip_proto; | 914 req->spec.ether_type = fk.basic.n_proto; 915 req->spec.ip_proto = fk.basic.ip_proto; |
859 860 if (fk.basic.n_proto == htons(ETH_P_IP)) { | 916 917 if (fk.basic.n_proto == htons(ETH_P_IP)) { |
861 spec.rem_host[0] = fk.addrs.v4addrs.src; 862 spec.loc_host[0] = fk.addrs.v4addrs.dst; | 918 req->spec.rem_host[0] = fk.addrs.v4addrs.src; 919 req->spec.loc_host[0] = fk.addrs.v4addrs.dst; |
863 } else { | 920 } else { |
864 memcpy(spec.rem_host, &fk.addrs.v6addrs.src, sizeof(struct in6_addr)); 865 memcpy(spec.loc_host, &fk.addrs.v6addrs.dst, sizeof(struct in6_addr)); | 921 memcpy(req->spec.rem_host, &fk.addrs.v6addrs.src, 922 sizeof(struct in6_addr)); 923 memcpy(req->spec.loc_host, &fk.addrs.v6addrs.dst, 924 sizeof(struct in6_addr)); |
866 } 867 | 925 } 926 |
868 spec.rem_port = fk.ports.src; 869 spec.loc_port = fk.ports.dst; | 927 req->spec.rem_port = fk.ports.src; 928 req->spec.loc_port = fk.ports.dst; |
870 | 929 |
871 rc = efx->type->filter_rfs_insert(efx, &spec); 872 if (rc < 0) 873 return rc; 874 875 /* Remember this so we can check whether to expire the filter later */ 876 channel = efx_get_channel(efx, rxq_index); 877 channel->rps_flow_id[rc] = flow_id; 878 ++channel->rfs_filters_added; 879 880 if (spec.ether_type == htons(ETH_P_IP)) 881 netif_info(efx, rx_status, efx->net_dev, 882 "steering %s %pI4:%u:%pI4:%u to queue %u [flow %u filter %d]\n", 883 (spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP", 884 spec.rem_host, ntohs(spec.rem_port), spec.loc_host, 885 ntohs(spec.loc_port), rxq_index, flow_id, rc); 886 else 887 netif_info(efx, rx_status, efx->net_dev, 888 "steering %s [%pI6]:%u:[%pI6]:%u to queue %u [flow %u filter %d]\n", 889 (spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP", 890 spec.rem_host, ntohs(spec.rem_port), spec.loc_host, 891 ntohs(spec.loc_port), rxq_index, flow_id, rc); 892 893 return rc; | 930 dev_hold(req->net_dev = net_dev); 931 INIT_WORK(&req->work, efx_filter_rfs_work); 932 req->rxq_index = rxq_index; 933 req->flow_id = flow_id; 934 schedule_work(&req->work); 935 return 0; |
894} 895 896bool __efx_filter_rfs_expire(struct efx_nic *efx, unsigned int quota) 897{ 898 bool (*expire_one)(struct efx_nic *efx, u32 flow_id, unsigned int index); 899 unsigned int channel_idx, index, size; 900 u32 flow_id; 901 | 936} 937 938bool __efx_filter_rfs_expire(struct efx_nic *efx, unsigned int quota) 939{ 940 bool (*expire_one)(struct efx_nic *efx, u32 flow_id, unsigned int index); 941 unsigned int channel_idx, index, size; 942 u32 flow_id; 943 |
902 if (!spin_trylock_bh(&efx->filter_lock)) | 944 if (!mutex_trylock(&efx->rps_mutex)) |
903 return false; | 945 return false; |
904 | |
905 expire_one = efx->type->filter_rfs_expire_one; 906 channel_idx = efx->rps_expire_channel; 907 index = efx->rps_expire_index; 908 size = efx->type->max_rx_ip_filters; 909 while (quota--) { 910 struct efx_channel *channel = efx_get_channel(efx, channel_idx); 911 flow_id = channel->rps_flow_id[index]; 912 --- 8 unchanged lines hidden (view full) --- 921 if (++channel_idx == efx->n_channels) 922 channel_idx = 0; 923 index = 0; 924 } 925 } 926 efx->rps_expire_channel = channel_idx; 927 efx->rps_expire_index = index; 928 | 946 expire_one = efx->type->filter_rfs_expire_one; 947 channel_idx = efx->rps_expire_channel; 948 index = efx->rps_expire_index; 949 size = efx->type->max_rx_ip_filters; 950 while (quota--) { 951 struct efx_channel *channel = efx_get_channel(efx, channel_idx); 952 flow_id = channel->rps_flow_id[index]; 953 --- 8 unchanged lines hidden (view full) --- 962 if (++channel_idx == efx->n_channels) 963 channel_idx = 0; 964 index = 0; 965 } 966 } 967 efx->rps_expire_channel = channel_idx; 968 efx->rps_expire_index = index; 969 |
929 spin_unlock_bh(&efx->filter_lock); | 970 mutex_unlock(&efx->rps_mutex); |
930 return true; 931} 932 933#endif /* CONFIG_RFS_ACCEL */ 934 935/** 936 * efx_filter_is_mc_recipient - test whether spec is a multicast recipient 937 * @spec: Specification to test --- 30 unchanged lines hidden --- | 971 return true; 972} 973 974#endif /* CONFIG_RFS_ACCEL */ 975 976/** 977 * efx_filter_is_mc_recipient - test whether spec is a multicast recipient 978 * @spec: Specification to test --- 30 unchanged lines hidden --- |