mac_soft_ring.c revision efe28d82661ce6701204798fb838fd29c6348931
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * CDDL HEADER START
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * The contents of this file are subject to the terms of the
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Common Development and Distribution License (the "License").
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * You may not use this file except in compliance with the License.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * or http://www.opensolaris.org/os/licensing.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * See the License for the specific language governing permissions
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * and limitations under the License.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * When distributing Covered Code, include this CDDL HEADER in each
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * If applicable, add the following below this CDDL HEADER, with the
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * fields enclosed by brackets "[]" replaced with your own identifying
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * information: Portions Copyright [yyyy] [name of copyright owner]
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * CDDL HEADER END
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Use is subject to license terms.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * General Soft rings - Simulating Rx rings in S/W.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Soft ring is a data abstraction containing a queue and a worker
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * thread and represents a hardware Rx ring in software. Each soft
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * ring set can have a collection of soft rings for separating
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * L3/L4 specific traffic (IPv4 from IPv6 or TCP from UDP) or for
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * allowing a higher degree of parallelism by sending traffic to
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * one of the soft rings for a SRS (using a hash on src IP or port).
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Each soft ring worker thread can be bound to a different CPU
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * allowing the processing for each soft ring to happen in parallel
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * and independent from each other.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Protocol soft rings:
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Each SRS has at an minimum 3 softrings. One each for IPv4 TCP,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * IPv4 UDP and rest (OTH - for IPv6 and everything else). The
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * SRS does dynamic polling and enforces link level bandwidth but
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * it does so for all traffic (IPv4 and IPv6 and all protocols) on
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * that link. However, each protocol layer wants a different
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * behaviour. For instance IPv4 TCP has per CPU squeues which
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * enforce their own polling and flow control so IPv4 TCP traffic
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * needs to go to a separate soft ring which can be polled by the
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * TCP squeue. It also allows TCP squeue to push back flow control
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * all the way to NIC hardware (if it puts its corresponding soft
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * ring in the poll mode and soft ring queue builds up, the
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * shared srs_poll_pkt_cnt goes up and SRS automatically stops
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * more packets from entering the system).
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Similarly, the UDP benefits from a DLS bypass and packet chaining
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * so sending it to a separate soft ring is desired. All the rest of
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * the traffic (including IPv6 is sent to OTH softring). The IPv6
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * traffic current goes through OTH softring and via DLS because
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * it need more processing to be done. Irrespective of the sap
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * (IPv4 or IPv6) or the transport, the dynamic polling, B/W enforcement,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * cpu assignment, fanout, etc apply to all traffic since they
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * are implement by the SRS which is agnostic to sap or transport.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Fanout soft rings:
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * On a multithreaded system, we can assign more CPU and multi thread
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * the stack by creating a soft ring per CPU and spreading traffic
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * based on a hash computed on src IP etc. Since we still need to
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * keep the protocol separation, we create a set of 3 soft ring per
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * CPU (specified by cpu list or degree of fanout).
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * NOTE: See the block level comment on top of mac_sched.c
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchistatic void mac_rx_soft_ring_drain(mac_soft_ring_t *);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchistatic void mac_soft_ring_fire(void *);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchistatic void mac_soft_ring_worker(mac_soft_ring_t *);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchistatic void mac_tx_soft_ring_drain(mac_soft_ring_t *);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchiuint32_t mac_tx_soft_ring_max_q_cnt = 100000;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#define ADD_SOFTRING_TO_SET(mac_srs, softring) { \
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if (mac_srs->srs_soft_ring_head == NULL) { \
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* ADD to the list */ \
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi mac_srs->srs_soft_ring_tail->s_ring_next = softring; \
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * mac_soft_ring_worker_wakeup
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Wake up the soft ring worker thread to process the queue as long
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * as no one else is processing it and upper layer (client) is still
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * ready to receive packets.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchimac_soft_ring_worker_wakeup(mac_soft_ring_t *ringp)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if (!(ringp->s_ring_state & S_RING_PROC) &&
* Protect against access from DR callbacks (mac_walk_srs_bind/unbind)
return (ringp);
cpu_t *
if (mac_soft_ring_thread_bind == 0) {
return (NULL);
return (NULL);
if (clear)
return (cp);
* packets are destined and s_ring_rx_arg1/s_ring_rx_arg2 are the
void *arg1;
int cnt;
if (tid != 0) {
tid = 0;
goto done;
done:
goto start;
thread_exit();
return (sring_blanked);
mblk_t *
int cnt = 0;
return (NULL);
cnt++;
return (head);
void *arg1;
void *arg2;
if (is_subflow) {
if (wakeup_required) {