| @@ -4968,16 +4968,16 @@ EXPORT_SYMBOL(rps_needed); · 4967 unmodified lines |
| 4968 | struct static_key_false rfs_needed __read_mostly; | 4968 | struct static_key_false rfs_needed __read_mostly; |
| 4969 | EXPORT_SYMBOL(rfs_needed); | 4969 | EXPORT_SYMBOL(rfs_needed); |
| 4970 | | 4970 | |
| 4971 | static u32 rfs_slot(u32 hash, const struct rps_dev_flow_table *flow_table) | 4971 | static u32 rfs_slot(u32 hash, rps_tag_ptr tag_ptr) |
| 4972 | { | 4972 | { |
| 4973 | return hash_32(hash, flow_table->log); | 4973 | return hash_32(hash, rps_tag_to_log(tag_ptr)); |
| 4974 | } | 4974 | } |
| 4975 | | 4975 | |
| 4976 | #ifdef CONFIG_RFS_ACCEL | 4976 | #ifdef CONFIG_RFS_ACCEL |
| 4977 | /** | 4977 | /** |
| 4978 | * rps_flow_is_active - check whether the flow is recently active. | 4978 | * rps_flow_is_active - check whether the flow is recently active. |
| 4979 | * @rflow: Specific flow to check activity. | 4979 | * @rflow: Specific flow to check activity. |
| 4980 | * @flow_table: per-queue flowtable that @rflow belongs to. | 4980 | * @log: ilog2(hashsize). |
| 4981 | * @cpu: CPU saved in @rflow. | 4981 | * @cpu: CPU saved in @rflow. |
| 4982 | * | 4982 | * |
| 4983 | * If the CPU has processed many packets since the flow's last activity | 4983 | * If the CPU has processed many packets since the flow's last activity |
| @@ -4986,7 +4986,7 @@ static u32 rfs_slot(u32 hash, const struct rps_dev_flow_table *flow_table) · 2 unmodified lines |
| 4986 | * Return: true if flow was recently active. | 4986 | * Return: true if flow was recently active. |
| 4987 | */ | 4987 | */ |
| 4988 | static bool rps_flow_is_active(struct rps_dev_flow *rflow, | 4988 | static bool rps_flow_is_active(struct rps_dev_flow *rflow, |
| 4989 | struct rps_dev_flow_table *flow_table, | 4989 | u8 log, |
| 4990 | unsigned int cpu) | 4990 | unsigned int cpu) |
| 4991 | { | 4991 | { |
| 4992 | unsigned int flow_last_active; | 4992 | unsigned int flow_last_active; |
| @@ -4999,7 +4999,7 @@ static bool rps_flow_is_active(struct rps_dev_flow *rflow, · 6 unmodified lines |
| 4999 | flow_last_active = READ_ONCE(rflow->last_qtail); | 4999 | flow_last_active = READ_ONCE(rflow->last_qtail); |
| 5000 | | 5000 | |
| 5001 | return (int)(sd_input_head - flow_last_active) < | 5001 | return (int)(sd_input_head - flow_last_active) < |
| 5002 | (int)(10 << flow_table->log); | 5002 | (int)(10 << log); |
| 5003 | } | 5003 | } |
| 5004 | #endif | 5004 | #endif |
| 5005 | | 5005 | |
| @@ -5011,9 +5011,10 @@ set_rps_cpu(struct net_device *dev, struct sk_buff *skb, · 5 unmodified lines |
| 5011 | u32 head; | 5011 | u32 head; |
| 5012 | #ifdef CONFIG_RFS_ACCEL | 5012 | #ifdef CONFIG_RFS_ACCEL |
| 5013 | struct netdev_rx_queue *rxqueue; | 5013 | struct netdev_rx_queue *rxqueue; |
| 5014 | struct rps_dev_flow_table *flow_table; | 5014 | struct rps_dev_flow *flow_table; |
| 5015 | struct rps_dev_flow *old_rflow; | 5015 | struct rps_dev_flow *old_rflow; |
| 5016 | struct rps_dev_flow *tmp_rflow; | 5016 | struct rps_dev_flow *tmp_rflow; |
| | 5017 | rps_tag_ptr q_tag_ptr; |
| 5017 | unsigned int tmp_cpu; | 5018 | unsigned int tmp_cpu; |
| 5018 | u16 rxq_index; | 5019 | u16 rxq_index; |
| 5019 | u32 flow_id; | 5020 | u32 flow_id; |
| @@ -5028,16 +5029,18 @@ set_rps_cpu(struct net_device *dev, struct sk_buff *skb, · 8 unmodified lines |
| 5028 | goto out; | 5029 | goto out; |
| 5029 | | 5030 | |
| 5030 | rxqueue = dev->_rx + rxq_index; | 5031 | rxqueue = dev->_rx + rxq_index; |
| 5031 | flow_table = rcu_dereference(rxqueue->rps_flow_table); | 5032 | q_tag_ptr = READ_ONCE(rxqueue->rps_flow_table); |
| 5032 | if (!flow_table) | 5033 | if (!q_tag_ptr) |
| 5033 | goto out; | 5034 | goto out; |
| 5034 | | 5035 | |
| 5035 | flow_id = rfs_slot(hash, flow_table); | 5036 | flow_id = rfs_slot(hash, q_tag_ptr); |
| 5036 | tmp_rflow = &flow_table->flows[flow_id]; | 5037 | flow_table = rps_tag_to_table(q_tag_ptr); |
| | 5038 | tmp_rflow = flow_table + flow_id; |
| 5037 | tmp_cpu = READ_ONCE(tmp_rflow->cpu); | 5039 | tmp_cpu = READ_ONCE(tmp_rflow->cpu); |
| 5038 | | 5040 | |
| 5039 | if (READ_ONCE(tmp_rflow->filter) != RPS_NO_FILTER) { | 5041 | if (READ_ONCE(tmp_rflow->filter) != RPS_NO_FILTER) { |
| 5040 | if (rps_flow_is_active(tmp_rflow, flow_table, | 5042 | if (rps_flow_is_active(tmp_rflow, |
| | 5043 | rps_tag_to_log(q_tag_ptr), |
| 5041 | tmp_cpu)) { | 5044 | tmp_cpu)) { |
| 5042 | if (hash != READ_ONCE(tmp_rflow->hash) || | 5045 | if (hash != READ_ONCE(tmp_rflow->hash) || |
| 5043 | next_cpu == tmp_cpu) | 5046 | next_cpu == tmp_cpu) |
| @@ -5076,8 +5079,7 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, · 32 unmodified lines |
| 5076 | struct rps_dev_flow **rflowp) | 5079 | struct rps_dev_flow **rflowp) |
| 5077 | { | 5080 | { |
| 5078 | struct netdev_rx_queue *rxqueue = dev->_rx; | 5081 | struct netdev_rx_queue *rxqueue = dev->_rx; |
| 5079 | struct rps_dev_flow_table *flow_table; | 5082 | rps_tag_ptr global_tag_ptr, q_tag_ptr; |
| 5080 | rps_tag_ptr global_tag_ptr; | | |
| 5081 | struct rps_map *map; | 5083 | struct rps_map *map; |
| 5082 | int cpu = -1; | 5084 | int cpu = -1; |
| 5083 | u32 tcpu; | 5085 | u32 tcpu; |
| @@ -5098,9 +5100,9 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, · 14 unmodified lines |
| 5098 | | 5100 | |
| 5099 | /* Avoid computing hash if RFS/RPS is not active for this rxqueue */ | 5101 | /* Avoid computing hash if RFS/RPS is not active for this rxqueue */ |
| 5100 | | 5102 | |
| 5101 | flow_table = rcu_dereference(rxqueue->rps_flow_table); | 5103 | q_tag_ptr = READ_ONCE(rxqueue->rps_flow_table); |
| 5102 | map = rcu_dereference(rxqueue->rps_map); | 5104 | map = rcu_dereference(rxqueue->rps_map); |
| 5103 | if (!flow_table && !map) | 5105 | if (!q_tag_ptr && !map) |
| 5104 | goto done; | 5106 | goto done; |
| 5105 | | 5107 | |
| 5106 | skb_reset_network_header(skb); | 5108 | skb_reset_network_header(skb); |
| @@ -5109,8 +5111,9 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, · 2 unmodified lines |
| 5109 | goto done; | 5111 | goto done; |
| 5110 | | 5112 | |
| 5111 | global_tag_ptr = READ_ONCE(net_hotdata.rps_sock_flow_table); | 5113 | global_tag_ptr = READ_ONCE(net_hotdata.rps_sock_flow_table); |
| 5112 | if (flow_table && global_tag_ptr) { | 5114 | if (q_tag_ptr && global_tag_ptr) { |
| 5113 | struct rps_sock_flow_table *sock_flow_table; | 5115 | struct rps_sock_flow_table *sock_flow_table; |
| | 5116 | struct rps_dev_flow *flow_table; |
| 5114 | struct rps_dev_flow *rflow; | 5117 | struct rps_dev_flow *rflow; |
| 5115 | u32 next_cpu; | 5118 | u32 next_cpu; |
| 5116 | u32 flow_id; | 5119 | u32 flow_id; |
| @@ -5130,7 +5133,9 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, · 13 unmodified lines |
| 5130 | /* OK, now we know there is a match, | 5133 | /* OK, now we know there is a match, |
| 5131 | * we can look at the local (per receive queue) flow table | 5134 | * we can look at the local (per receive queue) flow table |
| 5132 | */ | 5135 | */ |
| 5133 | rflow = &flow_table->flows[rfs_slot(hash, flow_table)]; | 5136 | flow_id = rfs_slot(hash, q_tag_ptr); |
| | 5137 | flow_table = rps_tag_to_table(q_tag_ptr); |
| | 5138 | rflow = flow_table + flow_id; |
| 5134 | tcpu = rflow->cpu; | 5139 | tcpu = rflow->cpu; |
| 5135 | | 5140 | |
| 5136 | /* | 5141 | /* |
| @@ -5190,19 +5195,23 @@ bool rps_may_expire_flow(struct net_device *dev, u16 rxq_index, · 53 unmodified lines |
| 5190 | u32 flow_id, u16 filter_id) | 5195 | u32 flow_id, u16 filter_id) |
| 5191 | { | 5196 | { |
| 5192 | struct netdev_rx_queue *rxqueue = dev->_rx + rxq_index; | 5197 | struct netdev_rx_queue *rxqueue = dev->_rx + rxq_index; |
| 5193 | struct rps_dev_flow_table *flow_table; | 5198 | struct rps_dev_flow *flow_table; |
| 5194 | struct rps_dev_flow *rflow; | 5199 | struct rps_dev_flow *rflow; |
| | 5200 | rps_tag_ptr q_tag_ptr; |
| 5195 | bool expire = true; | 5201 | bool expire = true; |
| | 5202 | u8 log; |
| 5196 | | 5203 | |
| 5197 | rcu_read_lock(); | 5204 | rcu_read_lock(); |
| 5198 | flow_table = rcu_dereference(rxqueue->rps_flow_table); | 5205 | q_tag_ptr = READ_ONCE(rxqueue->rps_flow_table); |
| 5199 | if (flow_table && flow_id < (1UL << flow_table->log)) { | 5206 | log = rps_tag_to_log(q_tag_ptr); |
| | 5207 | if (q_tag_ptr && flow_id < (1UL << log)) { |
| 5200 | unsigned int cpu; | 5208 | unsigned int cpu; |
| 5201 | | 5209 | |
| 5202 | rflow = &flow_table->flows[flow_id]; | 5210 | flow_table = rps_tag_to_table(q_tag_ptr); |
| | 5211 | rflow = flow_table + flow_id; |
| 5203 | cpu = READ_ONCE(rflow->cpu); | 5212 | cpu = READ_ONCE(rflow->cpu); |
| 5204 | if (READ_ONCE(rflow->filter) == filter_id && | 5213 | if (READ_ONCE(rflow->filter) == filter_id && |
| 5205 | rps_flow_is_active(rflow, flow_table, cpu)) | 5214 | rps_flow_is_active(rflow, log, cpu)) |
| 5206 | expire = false; | 5215 | expire = false; |
| 5207 | } | 5216 | } |
| 5208 | rcu_read_unlock(); | 5217 | rcu_read_unlock(); |