hyperv/hn: Move chimney buffer index and size to txdesc.
All RNDIS control messages have used SG list for a while. This makes the send context suitable for further refactoring. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8308
This commit is contained in:
parent
94dab02d88
commit
b7009d5392
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=307838
@ -117,7 +117,7 @@ hn_nvs_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact,
|
||||
/*
|
||||
* Execute the xact setup by the caller.
|
||||
*/
|
||||
hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
|
||||
hn_send_ctx_init(&sndc, hn_nvs_sent_xact, xact);
|
||||
|
||||
vmbus_xact_activate(xact);
|
||||
error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC,
|
||||
@ -669,34 +669,6 @@ hn_chim_free(struct hn_softc *sc, uint32_t chim_idx)
|
||||
atomic_clear_long(&sc->hn_chim_bmap[idx], mask);
|
||||
}
|
||||
|
||||
/*
|
||||
* Net VSC on send
|
||||
* Sends a packet on the specified Hyper-V device.
|
||||
* Returns 0 on success, non-zero on failure.
|
||||
*/
|
||||
int
|
||||
hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype,
|
||||
struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt)
|
||||
{
|
||||
struct hn_nvs_rndis rndis;
|
||||
int ret;
|
||||
|
||||
rndis.nvs_type = HN_NVS_TYPE_RNDIS;
|
||||
rndis.nvs_rndis_mtype = rndis_mtype;
|
||||
rndis.nvs_chim_idx = sndc->hn_chim_idx;
|
||||
rndis.nvs_chim_sz = sndc->hn_chim_sz;
|
||||
|
||||
if (gpa_cnt) {
|
||||
ret = hn_nvs_send_sglist(chan, gpa, gpa_cnt,
|
||||
&rndis, sizeof(rndis), sndc);
|
||||
} else {
|
||||
ret = hn_nvs_send(chan, VMBUS_CHANPKT_FLAG_RC,
|
||||
&rndis, sizeof(rndis), sndc);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
hn_nvs_alloc_subchans(struct hn_softc *sc, int *nsubch0)
|
||||
{
|
||||
|
@ -104,8 +104,8 @@ struct vmbus_channel;
|
||||
#define HN_XACT_REQ_SIZE (HN_XACT_REQ_PGCNT * PAGE_SIZE)
|
||||
#define HN_XACT_RESP_SIZE (HN_XACT_RESP_PGCNT * PAGE_SIZE)
|
||||
|
||||
#ifndef HN_USE_TXDESC_BUFRING
|
||||
struct hn_txdesc;
|
||||
#ifndef HN_USE_TXDESC_BUFRING
|
||||
SLIST_HEAD(hn_txdesc_list, hn_txdesc);
|
||||
#else
|
||||
struct buf_ring;
|
||||
@ -179,6 +179,7 @@ struct hn_tx_ring {
|
||||
bus_dma_tag_t hn_tx_data_dtag;
|
||||
uint64_t hn_csum_assist;
|
||||
|
||||
int (*hn_sendpkt)(struct hn_tx_ring *, struct hn_txdesc *);
|
||||
int hn_suspended;
|
||||
int hn_gpa_cnt;
|
||||
struct vmbus_gpa hn_gpa[NETVSC_PACKET_MAXPAGE];
|
||||
@ -276,13 +277,5 @@ struct hn_softc {
|
||||
#define HN_LINK_FLAG_LINKUP 0x0001
|
||||
#define HN_LINK_FLAG_NETCHG 0x0002
|
||||
|
||||
/*
|
||||
* Externs
|
||||
*/
|
||||
struct hn_send_ctx;
|
||||
|
||||
int hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype,
|
||||
struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt);
|
||||
|
||||
#endif /* __HV_NET_VSC_H__ */
|
||||
|
||||
|
@ -169,6 +169,8 @@ struct hn_txdesc {
|
||||
int refs;
|
||||
uint32_t flags; /* HN_TXD_FLAG_ */
|
||||
struct hn_send_ctx send_ctx;
|
||||
uint32_t chim_index;
|
||||
int chim_size;
|
||||
|
||||
bus_dmamap_t data_dmap;
|
||||
|
||||
@ -363,6 +365,8 @@ static void hn_tx_resume(struct hn_softc *, int);
|
||||
static void hn_tx_ring_qflush(struct hn_tx_ring *);
|
||||
static int netvsc_detach(device_t dev);
|
||||
static void hn_link_status(struct hn_softc *);
|
||||
static int hn_sendpkt_rndis_sglist(struct hn_tx_ring *, struct hn_txdesc *);
|
||||
static int hn_sendpkt_rndis_chim(struct hn_tx_ring *, struct hn_txdesc *);
|
||||
|
||||
static void hn_nvs_handle_notify(struct hn_softc *sc,
|
||||
const struct vmbus_chanpkt_hdr *pkt);
|
||||
@ -399,6 +403,57 @@ hn_set_lro_lenlim(struct hn_softc *sc, int lenlim)
|
||||
}
|
||||
#endif
|
||||
|
||||
static __inline int
|
||||
hn_nvs_send_rndis_sglist1(struct vmbus_channel *chan, uint32_t rndis_mtype,
|
||||
struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt)
|
||||
{
|
||||
struct hn_nvs_rndis rndis;
|
||||
|
||||
rndis.nvs_type = HN_NVS_TYPE_RNDIS;
|
||||
rndis.nvs_rndis_mtype = rndis_mtype;
|
||||
rndis.nvs_chim_idx = HN_NVS_CHIM_IDX_INVALID;
|
||||
rndis.nvs_chim_sz = 0;
|
||||
|
||||
return (hn_nvs_send_sglist(chan, gpa, gpa_cnt,
|
||||
&rndis, sizeof(rndis), sndc));
|
||||
}
|
||||
|
||||
int
|
||||
hn_nvs_send_rndis_ctrl(struct vmbus_channel *chan,
|
||||
struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt)
|
||||
{
|
||||
|
||||
return hn_nvs_send_rndis_sglist1(chan, HN_NVS_RNDIS_MTYPE_CTRL,
|
||||
sndc, gpa, gpa_cnt);
|
||||
}
|
||||
|
||||
static int
|
||||
hn_sendpkt_rndis_sglist(struct hn_tx_ring *txr, struct hn_txdesc *txd)
|
||||
{
|
||||
|
||||
KASSERT(txd->chim_index == HN_NVS_CHIM_IDX_INVALID &&
|
||||
txd->chim_size == 0, ("invalid rndis sglist txd"));
|
||||
return (hn_nvs_send_rndis_sglist1(txr->hn_chan, HN_NVS_RNDIS_MTYPE_DATA,
|
||||
&txd->send_ctx, txr->hn_gpa, txr->hn_gpa_cnt));
|
||||
}
|
||||
|
||||
static int
|
||||
hn_sendpkt_rndis_chim(struct hn_tx_ring *txr, struct hn_txdesc *txd)
|
||||
{
|
||||
struct hn_nvs_rndis rndis;
|
||||
|
||||
KASSERT(txd->chim_index != HN_NVS_CHIM_IDX_INVALID &&
|
||||
txd->chim_size > 0, ("invalid rndis chim txd"));
|
||||
|
||||
rndis.nvs_type = HN_NVS_TYPE_RNDIS;
|
||||
rndis.nvs_rndis_mtype = HN_NVS_RNDIS_MTYPE_DATA;
|
||||
rndis.nvs_chim_idx = txd->chim_index;
|
||||
rndis.nvs_chim_sz = txd->chim_size;
|
||||
|
||||
return (hn_nvs_send(txr->hn_chan, VMBUS_CHANPKT_FLAG_RC,
|
||||
&rndis, sizeof(rndis), &txd->send_ctx));
|
||||
}
|
||||
|
||||
static int
|
||||
hn_get_txswq_depth(const struct hn_tx_ring *txr)
|
||||
{
|
||||
@ -1038,8 +1093,8 @@ hn_tx_done(struct hn_send_ctx *sndc, struct hn_softc *sc,
|
||||
struct hn_txdesc *txd = sndc->hn_cbarg;
|
||||
struct hn_tx_ring *txr;
|
||||
|
||||
if (sndc->hn_chim_idx != HN_NVS_CHIM_IDX_INVALID)
|
||||
hn_chim_free(sc, sndc->hn_chim_idx);
|
||||
if (txd->chim_index != HN_NVS_CHIM_IDX_INVALID)
|
||||
hn_chim_free(sc, txd->chim_index);
|
||||
|
||||
txr = txd->txr;
|
||||
KASSERT(txr->hn_chan == chan,
|
||||
@ -1096,9 +1151,8 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
|
||||
int error, nsegs, i;
|
||||
struct mbuf *m_head = *m_head0;
|
||||
struct rndis_packet_msg *pkt;
|
||||
uint32_t send_buf_section_idx;
|
||||
int send_buf_section_size, pktlen;
|
||||
uint32_t *pi_data;
|
||||
int pktlen;
|
||||
|
||||
/*
|
||||
* extension points to the area reserved for the
|
||||
@ -1211,18 +1265,19 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
|
||||
*/
|
||||
if (pkt->rm_len < txr->hn_chim_size) {
|
||||
txr->hn_tx_chimney_tried++;
|
||||
send_buf_section_idx = hn_chim_alloc(txr->hn_sc);
|
||||
if (send_buf_section_idx != HN_NVS_CHIM_IDX_INVALID) {
|
||||
txd->chim_index = hn_chim_alloc(txr->hn_sc);
|
||||
if (txd->chim_index != HN_NVS_CHIM_IDX_INVALID) {
|
||||
uint8_t *dest = txr->hn_sc->hn_chim +
|
||||
(send_buf_section_idx * txr->hn_sc->hn_chim_szmax);
|
||||
(txd->chim_index * txr->hn_sc->hn_chim_szmax);
|
||||
|
||||
memcpy(dest, pkt, pktlen);
|
||||
dest += pktlen;
|
||||
m_copydata(m_head, 0, m_head->m_pkthdr.len, dest);
|
||||
|
||||
send_buf_section_size = pkt->rm_len;
|
||||
txd->chim_size = pkt->rm_len;
|
||||
txr->hn_gpa_cnt = 0;
|
||||
txr->hn_tx_chimney++;
|
||||
txr->hn_sendpkt = hn_sendpkt_rndis_chim;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@ -1267,14 +1322,14 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
|
||||
gpa->gpa_len = segs[i].ds_len;
|
||||
}
|
||||
|
||||
send_buf_section_idx = HN_NVS_CHIM_IDX_INVALID;
|
||||
send_buf_section_size = 0;
|
||||
txd->chim_index = HN_NVS_CHIM_IDX_INVALID;
|
||||
txd->chim_size = 0;
|
||||
txr->hn_sendpkt = hn_sendpkt_rndis_sglist;
|
||||
done:
|
||||
txd->m = m_head;
|
||||
|
||||
/* Set the completion routine */
|
||||
hn_send_ctx_init(&txd->send_ctx, hn_tx_done, txd,
|
||||
send_buf_section_idx, send_buf_section_size);
|
||||
hn_send_ctx_init(&txd->send_ctx, hn_tx_done, txd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1294,8 +1349,7 @@ hn_send_pkt(struct ifnet *ifp, struct hn_tx_ring *txr, struct hn_txdesc *txd)
|
||||
* Make sure that txd is not freed before ETHER_BPF_MTAP.
|
||||
*/
|
||||
hn_txdesc_hold(txd);
|
||||
error = hv_nv_on_send(txr->hn_chan, HN_NVS_RNDIS_MTYPE_DATA,
|
||||
&txd->send_ctx, txr->hn_gpa, txr->hn_gpa_cnt);
|
||||
error = txr->hn_sendpkt(txr, txd);
|
||||
if (!error) {
|
||||
ETHER_BPF_MTAP(ifp, txd->m);
|
||||
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
|
||||
|
@ -585,8 +585,7 @@ hn_rndis_xact_exec1(struct hn_softc *sc, struct vmbus_xact *xact, size_t reqlen,
|
||||
* message.
|
||||
*/
|
||||
vmbus_xact_activate(xact);
|
||||
error = hv_nv_on_send(sc->hn_prichan, HN_NVS_RNDIS_MTYPE_CTRL, sndc,
|
||||
gpa, gpa_cnt);
|
||||
error = hn_nvs_send_rndis_ctrl(sc->hn_prichan, sndc, gpa, gpa_cnt);
|
||||
if (error) {
|
||||
vmbus_xact_deactivate(xact);
|
||||
if_printf(sc->hn_ifp, "RNDIS ctrl send failed: %d\n", error);
|
||||
@ -1165,7 +1164,7 @@ hn_rndis_halt(struct hn_softc *sc)
|
||||
halt->rm_rid = hn_rndis_rid(sc);
|
||||
|
||||
/* No RNDIS completion; rely on NVS message send completion */
|
||||
hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
|
||||
hn_send_ctx_init(&sndc, hn_nvs_sent_xact, xact);
|
||||
hn_rndis_xact_exec1(sc, xact, sizeof(*halt), &sndc, &comp_len);
|
||||
|
||||
vmbus_xact_put(xact);
|
||||
|
@ -46,8 +46,6 @@ typedef void (*hn_sent_callback_t)
|
||||
struct hn_send_ctx {
|
||||
hn_sent_callback_t hn_cb;
|
||||
void *hn_cbarg;
|
||||
uint32_t hn_chim_idx;
|
||||
int hn_chim_sz;
|
||||
};
|
||||
|
||||
struct rndis_hash_info;
|
||||
@ -66,31 +64,18 @@ struct hn_recvinfo {
|
||||
uint32_t hash_value;
|
||||
};
|
||||
|
||||
#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \
|
||||
{ \
|
||||
.hn_cb = cb, \
|
||||
.hn_cbarg = cbarg, \
|
||||
.hn_chim_idx = HN_NVS_CHIM_IDX_INVALID, \
|
||||
.hn_chim_sz = 0 \
|
||||
#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \
|
||||
{ \
|
||||
.hn_cb = cb, \
|
||||
.hn_cbarg = cbarg \
|
||||
}
|
||||
|
||||
static __inline void
|
||||
hn_send_ctx_init(struct hn_send_ctx *sndc, hn_sent_callback_t cb,
|
||||
void *cbarg, uint32_t chim_idx, int chim_sz)
|
||||
hn_send_ctx_init(struct hn_send_ctx *sndc, hn_sent_callback_t cb, void *cbarg)
|
||||
{
|
||||
|
||||
sndc->hn_cb = cb;
|
||||
sndc->hn_cbarg = cbarg;
|
||||
sndc->hn_chim_idx = chim_idx;
|
||||
sndc->hn_chim_sz = chim_sz;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
hn_send_ctx_init_simple(struct hn_send_ctx *sndc, hn_sent_callback_t cb,
|
||||
void *cbarg)
|
||||
{
|
||||
|
||||
hn_send_ctx_init(sndc, cb, cbarg, HN_NVS_CHIM_IDX_INVALID, 0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
@ -134,6 +119,9 @@ void hn_nvs_detach(struct hn_softc *sc);
|
||||
int hn_nvs_alloc_subchans(struct hn_softc *sc, int *nsubch);
|
||||
void hn_nvs_sent_xact(struct hn_send_ctx *sndc, struct hn_softc *sc,
|
||||
struct vmbus_channel *chan, const void *data, int dlen);
|
||||
int hn_nvs_send_rndis_ctrl(struct vmbus_channel *chan,
|
||||
struct hn_send_ctx *sndc, struct vmbus_gpa *gpa,
|
||||
int gpa_cnt);
|
||||
|
||||
int hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen,
|
||||
const struct hn_recvinfo *info);
|
||||
|
Loading…
Reference in New Issue
Block a user