Index | Thread | Search

From:
Chris Cappuccio <chris@nmedia.net>
Subject:
Re: vio: Enable multiqueue
To:
Stefan Fritsch <sf@openbsd.org>
Cc:
Hrvoje Popovski <hrvoje@srce.hr>, tech@openbsd.org
Date:
Sun, 26 Jan 2025 12:59:13 -0800

Download raw body.

Thread
  • Chris Cappuccio:

    vio: Enable multiqueue

  • Alexander Bluhm:

    vio: Enable multiqueue

  • Stefan Fritsch [sf@openbsd.org] wrote:
    > 
    > diff --git a/sys/net/ifq.c b/sys/net/ifq.c
    > index 7368aa50a57..547cfb26d84 100644
    > --- a/sys/net/ifq.c
    > +++ b/sys/net/ifq.c
    > @@ -903,6 +903,8 @@ priq_idx(unsigned int nqueues, const struct mbuf *m)
    >  
    >  	if (ISSET(m->m_pkthdr.csum_flags, M_FLOWID))
    >  		flow = m->m_pkthdr.ph_flowid;
    > +	else
    > +		flow = cpu_number();
    >  
    >  	return (flow % nqueues);
    >  }
    
    
    If you generalize the idea of pf_pkt_hash, and stick it in the wrong place,
    it might look like this.
    
    Index: ifq.c
    ===================================================================
    RCS file: /cvs/src/sys/net/ifq.c,v
    retrieving revision 1.55
    diff -u -p -u -r1.55 ifq.c
    --- ifq.c	20 Nov 2024 02:18:45 -0000	1.55
    +++ ifq.c	26 Jan 2025 20:54:51 -0000
    @@ -29,6 +29,11 @@
     #include <net/if.h>
     #include <net/if_var.h>
     
    +#include <net/toeplitz.h>
    +#include <netinet/in.h>
    +#include <netinet/ip.h>
    +#include <netinet/ip6.h>
    +
     #if NBPFILTER > 0
     #include <net/bpf.h>
     #endif
    @@ -892,6 +897,60 @@ net_ifiq_sysctl(int *name, u_int namelen
     	return (error);
     }
     
    +unsigned int
    +ifq_pkt_hash(const struct mbuf *m)
    +{
    +	unsigned int hash = 0;
    +	uint8_t ip_version;
    +	const uint16_t *ports = NULL;
    +	const struct ip *ip_hdr;
    +	const struct ip6_hdr *ip6_hdr;
    +	uint8_t proto = 0;
    +
    +	ip_version = (*mtod(m, uint8_t *) >> 4);
    +	switch (ip_version) {
    +	case 4:
    +		ip_hdr = mtod(m, const struct ip *);
    +		if (m->m_len < (ip_hdr->ip_hl << 2)) {
    +			return 0;
    +		}
    +		hash ^= ip_hdr->ip_src.s_addr;
    +		hash ^= ip_hdr->ip_dst.s_addr;
    +		proto = ip_hdr->ip_p;
    +		if (proto == IPPROTO_TCP || proto == IPPROTO_UDP) {
    +			ports = (const uint16_t *)((uint8_t *)ip_hdr +
    +			    (ip_hdr->ip_hl << 2));
    +			hash ^= *(const uint32_t *)ports;
    +		}
    +		break;
    +	case 6:
    +		ip6_hdr = mtod(m, const struct ip6_hdr *);
    +		if (m->m_len < sizeof(struct ip6_hdr)) {
    +			return 0;
    +		}
    +		hash ^= ip6_hdr->ip6_src.__u6_addr.__u6_addr32[0];
    +		hash ^= ip6_hdr->ip6_src.__u6_addr.__u6_addr32[1];
    +		hash ^= ip6_hdr->ip6_src.__u6_addr.__u6_addr32[2];
    +		hash ^= ip6_hdr->ip6_src.__u6_addr.__u6_addr32[3];
    +		hash ^= ip6_hdr->ip6_dst.__u6_addr.__u6_addr32[0];
    +		hash ^= ip6_hdr->ip6_dst.__u6_addr.__u6_addr32[1];
    +		hash ^= ip6_hdr->ip6_dst.__u6_addr.__u6_addr32[2];
    +		hash ^= ip6_hdr->ip6_dst.__u6_addr.__u6_addr32[3];
    +		proto = ip6_hdr->ip6_nxt;
    +		if (proto == IPPROTO_TCP || proto == IPPROTO_UDP) {
    +			ports = (const uint16_t *)((uint8_t *)ip6_hdr +
    +			    sizeof(struct ip6_hdr));
    +			hash ^= *(const uint32_t *)ports;
    +		}
    +		break;
    +	default:
    +		return stoeplitz_n32(*(const uint32_t *)
    +		    mtod(m, const uint8_t *));
    +	}
    +
    +	return stoeplitz_n32(hash);
    +}
    +
     /*
      * priq implementation
      */
    @@ -903,6 +962,8 @@ priq_idx(unsigned int nqueues, const str
     
     	if (ISSET(m->m_pkthdr.csum_flags, M_FLOWID))
     		flow = m->m_pkthdr.ph_flowid;
    +	else
    +		flow = ifq_pkt_hash(m);
     
     	return (flow % nqueues);
     }
    
    
    
  • Chris Cappuccio:

    vio: Enable multiqueue

  • Alexander Bluhm:

    vio: Enable multiqueue