diff options
Diffstat (limited to 'usr/src/uts/sun4v/sys')
-rw-r--r-- | usr/src/uts/sun4v/sys/ldc_impl.h | 2 | ||||
-rw-r--r-- | usr/src/uts/sun4v/sys/vdsk_common.h | 2 | ||||
-rw-r--r-- | usr/src/uts/sun4v/sys/vio_mailbox.h | 15 | ||||
-rw-r--r-- | usr/src/uts/sun4v/sys/vio_util.h | 127 | ||||
-rw-r--r-- | usr/src/uts/sun4v/sys/vldc_impl.h | 3 | ||||
-rw-r--r-- | usr/src/uts/sun4v/sys/vnet.h | 1 | ||||
-rw-r--r-- | usr/src/uts/sun4v/sys/vnet_common.h | 4 | ||||
-rw-r--r-- | usr/src/uts/sun4v/sys/vnet_gen.h | 52 | ||||
-rw-r--r-- | usr/src/uts/sun4v/sys/vsw.h | 21 |
9 files changed, 196 insertions, 31 deletions
diff --git a/usr/src/uts/sun4v/sys/ldc_impl.h b/usr/src/uts/sun4v/sys/ldc_impl.h index 84fcc52b1f..4064ef99c3 100644 --- a/usr/src/uts/sun4v/sys/ldc_impl.h +++ b/usr/src/uts/sun4v/sys/ldc_impl.h @@ -427,6 +427,7 @@ struct ldc_chan { boolean_t intr_pending; /* TRUE if interrupts are pending */ + kmutex_t tx_lock; /* Transmit lock */ uint64_t tx_q_entries; /* Num entries in transmit queue */ uint64_t tx_q_va; /* Virtual addr of transmit queue */ uint64_t tx_q_ra; /* Real addr of transmit queue */ @@ -451,7 +452,6 @@ struct ldc_chan { uint8_t pkt_payload; /* Size of packet payload */ - uint32_t first_fragment; /* Seqid of first msg fragment */ uint32_t last_msg_snt; /* Seqid of last packet sent */ uint32_t last_ack_rcd; /* Seqid of last ACK recd */ uint32_t last_msg_rcd; /* Seqid of last packet received */ diff --git a/usr/src/uts/sun4v/sys/vdsk_common.h b/usr/src/uts/sun4v/sys/vdsk_common.h index b8251afea2..b4e6d4351f 100644 --- a/usr/src/uts/sun4v/sys/vdsk_common.h +++ b/usr/src/uts/sun4v/sys/vdsk_common.h @@ -79,7 +79,7 @@ extern "C" { #define VD_MAX_COOKIES ((VD_MAX_BLOCK_SIZE / PAGESIZE) + 1) #define VD_USEC_TIMEOUT 20000 #define VD_LDC_IDS_PROP "ldc-ids" -#define VD_LDC_QLEN 32 +#define VD_LDC_QLEN VD_DRING_LEN /* * Flags used by ioctl routines to indicate if a copyin/copyout is needed diff --git a/usr/src/uts/sun4v/sys/vio_mailbox.h b/usr/src/uts/sun4v/sys/vio_mailbox.h index 66de0722e6..c3b74ac9be 100644 --- a/usr/src/uts/sun4v/sys/vio_mailbox.h +++ b/usr/src/uts/sun4v/sys/vio_mailbox.h @@ -120,6 +120,13 @@ extern "C" { #define VIO_PAYLOAD_ELEMS (VIO_PAYLOAD_SZ / LDC_ELEM_SIZE) /* num words */ /* + * Peer dring processing state. Either actively processing dring + * or stopped. + */ +#define VIO_DP_ACTIVE 1 +#define VIO_DP_STOPPED 2 + +/* * VIO device message tag. * * These 64 bits are used as a common header for all VIO message types. @@ -169,7 +176,6 @@ typedef struct vio_ver_msg { uint64_t resv3[VIO_PAYLOAD_ELEMS - 1]; } vio_ver_msg_t; - /* * VIO Descriptor Ring Register message. * @@ -260,10 +266,15 @@ typedef struct vio_dring_msg { uint32_t start_idx; /* Indx of first updated elem */ int32_t end_idx; /* Indx of last updated elem */ + uint8_t dring_process_state; /* Processing state */ + /* * Padding. */ - uint64_t resv[VIO_PAYLOAD_ELEMS - 3]; + uint8_t resv1; + uint16_t resv2; + uint32_t resv3; + uint64_t resv4[VIO_PAYLOAD_ELEMS - 4]; } vio_dring_msg_t; /* diff --git a/usr/src/uts/sun4v/sys/vio_util.h b/usr/src/uts/sun4v/sys/vio_util.h new file mode 100644 index 0000000000..ab7a255f1e --- /dev/null +++ b/usr/src/uts/sun4v/sys/vio_util.h @@ -0,0 +1,127 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _VIO_UTIL_H +#define _VIO_UTIL_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/stream.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * A message is composed of three structures. A message block (mblk_t), a + * data block to which it points and a data buffer. desballoc(9F) allows + * the caller to specify the data buffer and a free function which will + * be invoked when freeb(9F) is called to free the message. This allows + * the user to reclaim and reuse the data buffer, as opposed to using + * allocb(9F) where the message block, data block and data buffer are + * all destroyed by freeb(). + * + * Note that even with desballoc the message and data blocks are destroyed + * by freeb() and must be recreated. It is only the data buffer which is + * preserved. + * + * The caller first creates a pool of vio_mblk_t's by invoking + * vio_create_mblks() and specifying the number of mblks and the size of the + * associated data buffers. Each vio_mblk_t contains a pointer to the + * mblk_t, a pointer to the data buffer and a function pointer to the + * reclaim function. The caller is returned a pointer to the pool which is + * used in subsequent allocation/destroy requests. + * + * The pool is managed as a circular queue with a head and tail pointer. + * Allocation requests result in the head index being incremented, mblks + * being returned to the pool result in the tail pointer being incremented. + * + * The pool can only be destroyed when all the mblks have been returned. It + * is the responsibility of the caller to ensure that all vio_allocb() + * requests have been completed before the pool is destroyed. + * + * + * vio_mblk_pool_t + * +-------------+ + * | tail |--------------------------------+ + * +-------------+ | + * | head |--------+ | + * +-------------+ | | + * ............... V V + * +-------------+ +-------+-------+-------+-------+ + * | quep |---->| vmp_t | vmp_t | vmp_t | vmp_t | + * +-------------+ +-------+-------+-------+-------+ + * | | | | | | + * ... | | | | +------------+ + * | | | +-->| data block | + * | | | +------------+ + * | | | +------------+ + * | | +-->| data block | + * | | +------------+ + * | | +------------+ + * | +-->| data block | + * | +------------+ + * | +------------+ + * +-->| data block | + * +------------+ + * + */ + +struct vio_mblk_pool; + +typedef struct vio_mblk { + uint8_t *datap; /* data buffer */ + mblk_t *mp; /* mblk using datap */ + frtn_t reclaim; /* mblk reclaim routine */ + struct vio_mblk_pool *vmplp; /* pointer to parent pool */ +} vio_mblk_t; + +typedef struct vio_mblk_pool { + struct vio_mblk_pool *nextp; /* next in a list */ + kmutex_t hlock; /* sync access to head */ + kmutex_t tlock; /* sync access to tail */ + vio_mblk_t *basep; /* base pointer to pool of vio_mblks */ + vio_mblk_t **quep; /* queue of free vio_mblks */ + uint8_t *datap; /* rx data buffer area */ + uint32_t head; /* queue head */ + uint32_t tail; /* queue tail */ + uint64_t quelen; /* queue len (# mblks) */ + uint64_t quemask; /* quelen - 1 */ + size_t mblk_size; /* data buf size of each mblk */ +} vio_mblk_pool_t; + +int vio_create_mblks(uint64_t num_mblks, + size_t mblk_size, vio_mblk_pool_t **); +int vio_destroy_mblks(vio_mblk_pool_t *); +mblk_t *vio_allocb(vio_mblk_pool_t *); +void vio_freeb(void *arg); + + +#ifdef __cplusplus +} +#endif + +#endif /* _VIO_UTIL_H */ diff --git a/usr/src/uts/sun4v/sys/vldc_impl.h b/usr/src/uts/sun4v/sys/vldc_impl.h index 8610344b42..ffdd97636b 100644 --- a/usr/src/uts/sun4v/sys/vldc_impl.h +++ b/usr/src/uts/sun4v/sys/vldc_impl.h @@ -52,6 +52,8 @@ extern "C" { #define VLDC_MINOR_MASK (VLDC_MAX_PORTS - 1) #define VLDC_INST_SHIFT 11 +#define VLDC_HVCTL_SVCNAME "hvctl" + /* get port number from minor number */ #define VLDCPORT(vldcp, minor) \ ((vldcp)->minor_tbl[(minor) & VLDC_MINOR_MASK].portno) @@ -95,6 +97,7 @@ typedef struct vldc_port { uint32_t mtu; /* port mtu */ caddr_t send_buf; /* send buffer */ caddr_t recv_buf; /* receive buffer */ + caddr_t cookie_buf; /* rd/wr cookie buffer */ uint64_t ldc_id; /* Channel number */ ldc_handle_t ldc_handle; /* Channel handle */ diff --git a/usr/src/uts/sun4v/sys/vnet.h b/usr/src/uts/sun4v/sys/vnet.h index c43af5bfab..53202f7601 100644 --- a/usr/src/uts/sun4v/sys/vnet.h +++ b/usr/src/uts/sun4v/sys/vnet.h @@ -44,6 +44,7 @@ extern "C" { #define VNET_LDCWD_INTERVAL 1000 /* watchdog freq in msec */ #define VNET_LDCWD_TXTIMEOUT 1000 /* tx timeout in msec */ #define VNET_LDC_QLEN 1024 /* ldc qlen */ +#define VNET_NRBUFS 512 /* number of receive bufs */ /* * vnet proxy transport layer information. There is one instance of this for diff --git a/usr/src/uts/sun4v/sys/vnet_common.h b/usr/src/uts/sun4v/sys/vnet_common.h index feed7025a2..575db18efb 100644 --- a/usr/src/uts/sun4v/sys/vnet_common.h +++ b/usr/src/uts/sun4v/sys/vnet_common.h @@ -43,11 +43,13 @@ extern "C" { */ /* max # of cookies per frame size */ -#define MAX_COOKIES ((ETHERMAX >> MMU_PAGESHIFT) + 2) +#define MAX_COOKIES ((ETHERMAX >> MMU_PAGESHIFT) + 2ULL) /* initial send sequence number */ #define VNET_ISS 0x1 +#define VNET_IPALIGN 6 /* padding for IP header alignment */ + /* vnet descriptor */ typedef struct vnet_public_desc { vio_dring_entry_hdr_t hdr; /* descriptor header */ diff --git a/usr/src/uts/sun4v/sys/vnet_gen.h b/usr/src/uts/sun4v/sys/vnet_gen.h index c6ad5fe8c0..3166a3412d 100644 --- a/usr/src/uts/sun4v/sys/vnet_gen.h +++ b/usr/src/uts/sun4v/sys/vnet_gen.h @@ -69,7 +69,7 @@ extern "C" { #define LDC_TO_VNET(ldcp) ((ldcp)->portp->vgenp->vnetp) #define LDC_TO_VGEN(ldcp) ((ldcp)->portp->vgenp) -#define VGEN_TX_DBLK_SZ 2048 /* tx data buffer size */ +#define VGEN_DBLK_SZ 2048 /* data buffer size */ #define VGEN_LDC_UP_DELAY 100 /* usec delay between ldc_up retries */ /* get the address of next tbuf */ @@ -107,7 +107,6 @@ typedef struct vgen_priv_desc { ldc_mem_handle_t memhandle; /* mem handle for data */ caddr_t datap; /* prealloc'd tx data buffer */ uint64_t datalen; /* total actual datalen */ - uint64_t seqnum; /* sequence number of pkt */ uint64_t ncookies; /* num ldc_mem_cookies */ ldc_mem_cookie_t memcookie[MAX_COOKIES]; /* data cookies */ } vgen_private_desc_t; @@ -147,13 +146,10 @@ typedef struct vgen_ver { typedef struct vgen_stats { /* Link Input/Output stats */ - uint64_t ipackets; - uint64_t ierrors; - uint64_t opackets; - uint64_t oerrors; -#if 0 - uint64_t collisions; -#endif + uint64_t ipackets; /* # rx packets */ + uint64_t ierrors; /* # rx error */ + uint64_t opackets; /* # tx packets */ + uint64_t oerrors; /* # tx error */ /* MIB II variables */ uint64_t rbytes; /* # bytes received */ @@ -166,17 +162,18 @@ typedef struct vgen_stats { uint32_t noxmtbuf; /* # xmit packets discarded */ /* Tx Statistics */ - uint32_t tx_no_desc; - uint32_t tx_allocb_fail; + uint32_t tx_no_desc; /* # out of transmit descriptors */ /* Rx Statistics */ - uint32_t rx_no_desc; - uint32_t rx_allocb_fail; - uint32_t rx_lost_pkts; + uint32_t rx_allocb_fail; /* # rx buf allocb() failures */ + uint32_t rx_vio_allocb_fail; /* # vio_allocb() failures */ + uint32_t rx_lost_pkts; /* # rx lost packets */ /* Callback statistics */ - uint32_t callbacks; - uint32_t dring_data_acks; + uint32_t callbacks; /* # callbacks */ + uint32_t dring_data_acks; /* # dring data acks recvd */ + uint32_t dring_stopped_acks; /* # dring stopped acks recvd */ + uint32_t dring_data_msgs; /* # dring data msgs sent */ } vgen_stats_t; @@ -190,9 +187,7 @@ typedef struct vgen_kstats { kstat_named_t opackets; kstat_named_t opackets64; kstat_named_t oerrors; -#if 0 - kstat_named_t collisions; -#endif + /* * required by kstat for MIB II objects(RFC 1213) */ @@ -208,17 +203,18 @@ typedef struct vgen_kstats { kstat_named_t noxmtbuf; /* MIB - ifOutDiscards */ /* Tx Statistics */ - kstat_named_t tx_no_desc; - kstat_named_t tx_allocb_fail; + kstat_named_t tx_no_desc; /* # out of transmit descriptors */ /* Rx Statistics */ - kstat_named_t rx_no_desc; - kstat_named_t rx_allocb_fail; - kstat_named_t rx_lost_pkts; + kstat_named_t rx_allocb_fail; /* # rx buf allocb failures */ + kstat_named_t rx_vio_allocb_fail; /* # vio_allocb() failures */ + kstat_named_t rx_lost_pkts; /* # rx lost packets */ /* Callback statistics */ - kstat_named_t callbacks; - kstat_named_t dring_data_acks; + kstat_named_t callbacks; /* # callbacks */ + kstat_named_t dring_data_acks; /* # dring data acks recvd */ + kstat_named_t dring_stopped_acks; /* # dring stopped acks recvd */ + kstat_named_t dring_data_msgs; /* # dring data msgs sent */ } vgen_kstats_t; @@ -277,6 +273,8 @@ typedef struct vgen_ldc { uint32_t next_rxi; /* next expected recv index */ uint32_t num_rxds; /* number of rx descriptors */ caddr_t tx_datap; /* prealloc'd tx data area */ + vio_mblk_pool_t *rmp; /* rx mblk pool */ + uint32_t num_rbufs; /* number of rx bufs */ /* misc */ uint32_t flags; /* flags */ @@ -284,6 +282,7 @@ typedef struct vgen_ldc { boolean_t need_ldc_reset; /* ldc_reset needed */ boolean_t need_mcast_sync; /* sync mcast table with vsw */ uint32_t hretries; /* handshake retry count */ + boolean_t resched_peer; /* send tx msg to peer */ /* channel statistics */ vgen_stats_t *statsp; /* channel statistics */ @@ -329,6 +328,7 @@ typedef struct vgen { struct ether_addr *mctab; /* multicast addr table */ uint32_t mcsize; /* allocated size of mctab */ uint32_t mccount; /* # of valid addrs in mctab */ + vio_mblk_pool_t *rmp; /* rx mblk pools to be freed */ } vgen_t; #ifdef __cplusplus diff --git a/usr/src/uts/sun4v/sys/vsw.h b/usr/src/uts/sun4v/sys/vsw.h index fccb3c6fb8..b1df247547 100644 --- a/usr/src/uts/sun4v/sys/vsw.h +++ b/usr/src/uts/sun4v/sys/vsw.h @@ -82,6 +82,7 @@ extern "C" { #include <sys/vio_mailbox.h> #include <sys/vnet_common.h> #include <sys/ethernet.h> +#include <sys/vio_util.h> /* * Default message type. @@ -209,9 +210,21 @@ typedef struct ver_sup { #define VSW_MAX_COOKIES ((ETHERMTU >> MMU_PAGESHIFT) + 2) /* + * Size and number of mblks to be created in free pool. + */ +#define VSW_MBLK_SIZE 2048 +#define VSW_NUM_MBLKS 1024 + +/* * Private descriptor */ typedef struct vsw_private_desc { + /* + * Below lock must be held when accessing the state of + * a descriptor on either the private or public sections + * of the ring. + */ + kmutex_t dstate_lock; uint64_t dstate; vnet_public_desc_t *descp; ldc_mem_handle_t memhandle; @@ -237,6 +250,10 @@ typedef struct dring_info { ldc_dring_handle_t handle; uint64_t ident; /* identifier sent to peer */ uint64_t end_idx; /* last idx processed */ + int64_t last_ack_recv; + + kmutex_t restart_lock; + boolean_t restart_reqd; /* send restart msg */ /* * base address of private and public portions of the @@ -258,6 +275,7 @@ typedef struct lane { uint64_t lstate; /* Lane state */ uint32_t ver_major:16, /* Version major number */ ver_minor:16; /* Version minor number */ + kmutex_t seq_lock; uint64_t seq_num; /* Sequence number */ uint64_t mtu; /* ETHERMTU */ uint64_t addr; /* Unique physical address */ @@ -295,6 +313,7 @@ typedef struct vsw_ldc { lane_t lane_in; /* Inbound lane */ lane_t lane_out; /* Outbound lane */ uint8_t dev_class; /* Peer device class */ + vio_mblk_pool_t *rxh; /* Receive pool handle */ } vsw_ldc_t; /* list of ldcs per port */ @@ -407,6 +426,8 @@ typedef struct vsw { mod_hash_t *mfdb; /* multicast FDB */ krwlock_t mfdbrw; /* rwlock for mFDB */ + vio_mblk_pool_t *rxh; /* Receive pool handle */ + /* mac layer */ mac_handle_t mh; mac_rx_handle_t mrh; |