<div dir="ltr">hi all:<div>      I&#39;m read the source code of RPS and RFS, I think the key function of RPS and RFS is get_rps_cpu(), and </div><div>It&#39;s codes is:</div><div>###############################################################</div><div><div>3079 static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,</div><div>3080                struct rps_dev_flow **rflowp)</div><div>3081 {</div><div>3082     struct netdev_rx_queue *rxqueue;</div><div>3083     struct rps_map *map;</div><div>3084     struct rps_dev_flow_table *flow_table;</div><div>3085     struct rps_sock_flow_table *sock_flow_table;</div><div>3086     int cpu = -1;</div><div>3087     u16 tcpu;</div><div>3088     u32 hash;</div><div>3089 </div><div>3090     if (skb_rx_queue_recorded(skb)) {</div><div>3091         u16 index = skb_get_rx_queue(skb);</div><div>3092         if (unlikely(index &gt;= dev-&gt;real_num_rx_queues)) {</div><div>3093             WARN_ONCE(dev-&gt;real_num_rx_queues &gt; 1,</div><div>3094                   &quot;%s received packet on queue %u, but number &quot;</div><div>3095                   &quot;of RX queues is %u\n&quot;,</div><div>3096                   dev-&gt;name, index, dev-&gt;real_num_rx_queues);</div><div>3097             goto done;</div><div>3098         }</div><div>3099         rxqueue = dev-&gt;_rx + index;</div><div>3100     } else</div><div>3101         rxqueue = dev-&gt;_rx;</div><div>3102 </div><div>3103     map = rcu_dereference(rxqueue-&gt;rps_map);</div><div>3104     if (map) {</div><div>3105         if (map-&gt;len == 1 &amp;&amp;</div><div>3106             !rcu_access_pointer(rxqueue-&gt;rps_flow_table)) {</div><div>3107             tcpu = map-&gt;cpus[0];</div><div>3108             if (cpu_online(tcpu))</div><div>3109                 cpu = tcpu;</div><div>3110             goto done;</div><div>3111         }</div><div>3112     } else if (!rcu_access_pointer(rxqueue-&gt;rps_flow_table)) {</div><div>3113         goto done;</div></div><div><div>3114     }</div><div>3115 </div><div>3116     skb_reset_network_header(skb);</div><div>3117     hash = skb_get_hash(skb);</div><div>3118     if (!hash)</div><div>3119         goto done;</div><div>3120 </div><div>3121     flow_table = rcu_dereference(rxqueue-&gt;rps_flow_table);</div><div>3122     sock_flow_table = rcu_dereference(rps_sock_flow_table);</div><div>3123     if (flow_table &amp;&amp; sock_flow_table) {</div><div>3124         u16 next_cpu;</div><div>3125         struct rps_dev_flow *rflow;</div><div>3126 </div><div>3127         rflow = &amp;flow_table-&gt;flows[hash &amp; flow_table-&gt;mask];</div><div>3128         tcpu = rflow-&gt;cpu;</div><div>3129 </div><div>3130         next_cpu = sock_flow_table-&gt;ents[hash &amp; sock_flow_table-&gt;mask];</div><div>3131 </div><div>3132         /*</div><div>3133          * If the desired CPU (where last recvmsg was done) is</div><div>3134          * different from current CPU (one in the rx-queue flow</div><div>3135          * table entry), switch if one of the following holds:</div><div>3136          *   - Current CPU is unset (equal to RPS_NO_CPU).</div><div>3137          *   - Current CPU is offline.</div><div>3138          *   - The current CPU&#39;s queue tail has advanced beyond the</div><div>3139          *     last packet that was enqueued using this table entry.</div><div>3140          *     This guarantees that all previous packets for the flow</div><div>3141          *     have been dequeued, thus preserving in order delivery.</div><div>3142          */</div><div>3143         if (unlikely(tcpu != next_cpu) &amp;&amp;</div><div>3144             (tcpu == RPS_NO_CPU || !cpu_online(tcpu) ||</div><div>3145              ((int)(per_cpu(softnet_data, tcpu).input_queue_head -</div><div>3146               rflow-&gt;last_qtail)) &gt;= 0)) {</div><div>3147             tcpu = next_cpu;</div><div>3148             rflow = set_rps_cpu(dev, skb, rflow, next_cpu);</div><div>3149         }</div><div>3150 </div><div>3151         if (tcpu != RPS_NO_CPU &amp;&amp; cpu_online(tcpu)) {</div><div>3152             *rflowp = rflow;</div><div>3153             cpu = tcpu;</div><div>3154             goto done;</div><div>3155         }</div><div>3156     }</div><div>3157 </div></div><div><div>3158     if (map) {</div><div>3159         tcpu = map-&gt;cpus[reciprocal_scale(hash, map-&gt;len)];</div><div>3160         if (cpu_online(tcpu)) {</div><div>3161             cpu = tcpu;</div><div>3162             goto done;</div><div>3163         }</div><div>3164     }</div><div>3165 </div><div>3166 done:</div><div>3167     return cpu;</div><div>3168 }</div></div><div>###############################################################</div><div>I know the RPS/RFS get the CPU id by this function.I think RPS can&#39;t work, </div><div>when RFS is active, beacuse the implementation of RPS is between 3158 and 3163. </div><div>and the codes between 3123 and 3156 are used for RFS. </div><div><br></div><div>I think RPS is work just in this two <font color="#434343" face="Arial, sans-serif"><span style="font-size:14px;line-height:24px"> conditions:</span></font></div><div><font color="#434343" face="Arial, sans-serif"><span style="font-size:14px;line-height:24px">1.  When the packet first arrived this host,  the value of tcpu and next_cpu are RPS_NO_CPU.</span></font></div><div><font color="#434343" face="Arial, sans-serif"><span style="font-size:14px;line-height:24px">2. When the d</span></font><span style="color:rgb(67,67,67);font-family:Arial,sans-serif;font-size:14px;line-height:24px">estination of packet is not this host, the value of tcpu and next_cpu always are RPS_NO_CPU.</span></div><div><br></div><div>My question is: If the RFS is enable, the RPS can&#39;t work?</div><div><br></div><div>Thank you. </div><div><font color="#434343" face="Arial, sans-serif"><span style="font-size:14px;line-height:24px">  </span></font><span class="" style="color:rgb(67,67,67);font-family:Arial,sans-serif;font-size:14px;line-height:24px"></span></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div></div>