svn commit: r307473 - stable/11/sys/dev/hyperv/netvsc
Sepherosa Ziehau
sephe at FreeBSD.org
Mon Oct 17 05:37:24 UTC 2016
Author: sephe
Date: Mon Oct 17 05:37:22 2016
New Revision: 307473
URL: https://svnweb.freebsd.org/changeset/base/307473
Log:
MFC 303867,303901
303867
hyperv/hn: Move gpa array out of netvsc_packet.
Prepare to deprecate the netvsc_packet.
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D7436
303901
hyperv/hn: Reorganize send done callback.
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D7450
Added:
stable/11/sys/dev/hyperv/netvsc/if_hnvar.h
- copied unchanged from r303901, head/sys/dev/hyperv/netvsc/if_hnvar.h
Modified:
stable/11/sys/dev/hyperv/netvsc/hv_net_vsc.c
stable/11/sys/dev/hyperv/netvsc/hv_net_vsc.h
stable/11/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.c
stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.h
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/dev/hyperv/netvsc/hv_net_vsc.c
==============================================================================
--- stable/11/sys/dev/hyperv/netvsc/hv_net_vsc.c Mon Oct 17 05:33:41 2016 (r307472)
+++ stable/11/sys/dev/hyperv/netvsc/hv_net_vsc.c Mon Oct 17 05:37:22 2016 (r307473)
@@ -68,6 +68,12 @@ static void hv_nv_on_receive_completion(
static void hv_nv_on_receive(netvsc_dev *net_dev,
struct hn_rx_ring *rxr, struct vmbus_channel *chan,
const struct vmbus_chanpkt_hdr *pkt);
+static void hn_nvs_sent_none(struct hn_send_ctx *sndc,
+ struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
+ const struct nvsp_msg_ *msg);
+
+static struct hn_send_ctx hn_send_ctx_none =
+ HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL);
/*
*
@@ -141,6 +147,7 @@ hv_nv_get_next_send_section(netvsc_dev *
static int
hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc)
{
+ struct hn_send_ctx sndc;
netvsc_dev *net_dev;
nvsp_msg *init_pkt;
int ret = 0;
@@ -189,9 +196,10 @@ hv_nv_init_rx_buffer_with_net_vsp(struct
/* Send the gpadl notification request */
+ hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL);
ret = vmbus_chan_send(sc->hn_prichan,
VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
- init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt);
+ init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc);
if (ret != 0) {
goto cleanup;
}
@@ -240,6 +248,7 @@ exit:
static int
hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc)
{
+ struct hn_send_ctx sndc;
netvsc_dev *net_dev;
nvsp_msg *init_pkt;
int ret = 0;
@@ -287,9 +296,10 @@ hv_nv_init_send_buffer_with_net_vsp(stru
/* Send the gpadl notification request */
+ hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL);
ret = vmbus_chan_send(sc->hn_prichan,
VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
- init_pkt, sizeof(nvsp_msg), (uint64_t)init_pkt);
+ init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc);
if (ret != 0) {
goto cleanup;
}
@@ -348,8 +358,7 @@ hv_nv_destroy_rx_buffer(netvsc_dev *net_
ret = vmbus_chan_send(net_dev->sc->hn_prichan,
VMBUS_CHANPKT_TYPE_INBAND, 0, revoke_pkt, sizeof(nvsp_msg),
- (uint64_t)(uintptr_t)revoke_pkt);
-
+ (uint64_t)(uintptr_t)&hn_send_ctx_none);
/*
* If we failed here, we might as well return and have a leak
* rather than continue and a bugchk
@@ -414,9 +423,8 @@ hv_nv_destroy_send_buffer(netvsc_dev *ne
NETVSC_SEND_BUFFER_ID;
ret = vmbus_chan_send(net_dev->sc->hn_prichan,
- VMBUS_CHANPKT_TYPE_INBAND, 0,
- revoke_pkt, sizeof(nvsp_msg),
- (uint64_t)(uintptr_t)revoke_pkt);
+ VMBUS_CHANPKT_TYPE_INBAND, 0, revoke_pkt, sizeof(nvsp_msg),
+ (uint64_t)(uintptr_t)&hn_send_ctx_none);
/*
* If we failed here, we might as well return and have a leak
* rather than continue and a bugchk
@@ -466,6 +474,7 @@ static int
hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, netvsc_dev *net_dev,
uint32_t nvsp_ver)
{
+ struct hn_send_ctx sndc;
nvsp_msg *init_pkt;
int ret;
@@ -480,9 +489,10 @@ hv_nv_negotiate_nvsp_protocol(struct hn_
init_pkt->msgs.init_msgs.init.protocol_version_2 = nvsp_ver;
/* Send the init request */
+ hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL);
ret = vmbus_chan_send(sc->hn_prichan,
VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
- init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt);
+ init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc);
if (ret != 0)
return (-1);
@@ -524,7 +534,7 @@ hv_nv_send_ndis_config(struct hn_softc *
/* Send the configuration packet */
ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0,
- init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt);
+ init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&hn_send_ctx_none);
if (ret != 0)
return (-EINVAL);
@@ -602,7 +612,7 @@ hv_nv_connect_to_vsp(struct hn_softc *sc
/* Send the init request */
ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0,
- init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt);
+ init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&hn_send_ctx_none);
if (ret != 0) {
goto cleanup;
}
@@ -731,6 +741,43 @@ hv_nv_on_device_remove(struct hn_softc *
return (0);
}
+void
+hn_nvs_sent_wakeup(struct hn_send_ctx *sndc __unused,
+ struct netvsc_dev_ *net_dev, struct vmbus_channel *chan __unused,
+ const struct nvsp_msg_ *msg)
+{
+ /* Copy the response back */
+ memcpy(&net_dev->channel_init_packet, msg, sizeof(nvsp_msg));
+ sema_post(&net_dev->channel_init_sema);
+}
+
+static void
+hn_nvs_sent_none(struct hn_send_ctx *sndc __unused,
+ struct netvsc_dev_ *net_dev __unused, struct vmbus_channel *chan __unused,
+ const struct nvsp_msg_ *msg __unused)
+{
+ /* EMPTY */
+}
+
+void
+hn_chim_free(struct netvsc_dev_ *net_dev, uint32_t chim_idx)
+{
+ u_long mask;
+ uint32_t idx;
+
+ idx = chim_idx / BITS_PER_LONG;
+ KASSERT(idx < net_dev->bitsmap_words,
+ ("invalid chimney index 0x%x", chim_idx));
+
+ mask = 1UL << (chim_idx % BITS_PER_LONG);
+ KASSERT(net_dev->send_section_bitsmap[idx] & mask,
+ ("index bitmap 0x%lx, chimney index %u, "
+ "bitmap idx %d, bitmask 0x%lx",
+ net_dev->send_section_bitsmap[idx], chim_idx, idx, mask));
+
+ atomic_clear_long(&net_dev->send_section_bitsmap[idx], mask);
+}
+
/*
* Net VSC on send completion
*/
@@ -738,59 +785,15 @@ static void
hv_nv_on_send_completion(netvsc_dev *net_dev, struct vmbus_channel *chan,
const struct vmbus_chanpkt_hdr *pkt)
{
- const nvsp_msg *nvsp_msg_pkt;
- netvsc_packet *net_vsc_pkt;
+ struct hn_send_ctx *sndc;
- nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkt);
-
- if (nvsp_msg_pkt->hdr.msg_type == nvsp_msg_type_init_complete
- || nvsp_msg_pkt->hdr.msg_type
- == nvsp_msg_1_type_send_rx_buf_complete
- || nvsp_msg_pkt->hdr.msg_type
- == nvsp_msg_1_type_send_send_buf_complete
- || nvsp_msg_pkt->hdr.msg_type
- == nvsp_msg5_type_subchannel) {
- /* Copy the response back */
- memcpy(&net_dev->channel_init_packet, nvsp_msg_pkt,
- sizeof(nvsp_msg));
- sema_post(&net_dev->channel_init_sema);
- } else if (nvsp_msg_pkt->hdr.msg_type ==
- nvsp_msg_1_type_send_rndis_pkt_complete) {
- /* Get the send context */
- net_vsc_pkt =
- (netvsc_packet *)(unsigned long)pkt->cph_xactid;
- if (NULL != net_vsc_pkt) {
- if (net_vsc_pkt->send_buf_section_idx !=
- NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
- u_long mask;
- int idx;
-
- idx = net_vsc_pkt->send_buf_section_idx /
- BITS_PER_LONG;
- KASSERT(idx < net_dev->bitsmap_words,
- ("invalid section index %u",
- net_vsc_pkt->send_buf_section_idx));
- mask = 1UL <<
- (net_vsc_pkt->send_buf_section_idx %
- BITS_PER_LONG);
-
- KASSERT(net_dev->send_section_bitsmap[idx] &
- mask,
- ("index bitmap 0x%lx, section index %u, "
- "bitmap idx %d, bitmask 0x%lx",
- net_dev->send_section_bitsmap[idx],
- net_vsc_pkt->send_buf_section_idx,
- idx, mask));
- atomic_clear_long(
- &net_dev->send_section_bitsmap[idx], mask);
- }
-
- /* Notify the layer above us */
- net_vsc_pkt->compl.send.on_send_completion(chan,
- net_vsc_pkt->compl.send.send_completion_context);
-
- }
- }
+ sndc = (struct hn_send_ctx *)(uintptr_t)pkt->cph_xactid;
+ sndc->hn_cb(sndc, net_dev, chan, VMBUS_CHANPKT_CONST_DATA(pkt));
+ /*
+ * NOTE:
+ * 'sndc' CAN NOT be accessed anymore, since it can be freed by
+ * its callback.
+ */
}
/*
@@ -799,13 +802,14 @@ hv_nv_on_send_completion(netvsc_dev *net
* Returns 0 on success, non-zero on failure.
*/
int
-hv_nv_on_send(struct vmbus_channel *chan, netvsc_packet *pkt)
+hv_nv_on_send(struct vmbus_channel *chan, bool is_data_pkt,
+ struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt)
{
nvsp_msg send_msg;
int ret;
send_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt;
- if (pkt->is_data_pkt) {
+ if (is_data_pkt) {
/* 0 is RMC_DATA */
send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 0;
} else {
@@ -814,17 +818,17 @@ hv_nv_on_send(struct vmbus_channel *chan
}
send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_idx =
- pkt->send_buf_section_idx;
+ sndc->hn_chim_idx;
send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_size =
- pkt->send_buf_section_size;
+ sndc->hn_chim_sz;
- if (pkt->gpa_cnt) {
- ret = vmbus_chan_send_sglist(chan, pkt->gpa, pkt->gpa_cnt,
- &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt);
+ if (gpa_cnt) {
+ ret = vmbus_chan_send_sglist(chan, gpa, gpa_cnt,
+ &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)sndc);
} else {
ret = vmbus_chan_send(chan,
VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
- &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt);
+ &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)sndc);
}
return (ret);
Modified: stable/11/sys/dev/hyperv/netvsc/hv_net_vsc.h
==============================================================================
--- stable/11/sys/dev/hyperv/netvsc/hv_net_vsc.h Mon Oct 17 05:33:41 2016 (r307472)
+++ stable/11/sys/dev/hyperv/netvsc/hv_net_vsc.h Mon Oct 17 05:37:22 2016 (r307473)
@@ -1112,33 +1112,10 @@ typedef void (*pfn_on_send_rx_completion
#endif
typedef struct netvsc_packet_ {
- uint8_t is_data_pkt; /* One byte */
- uint16_t vlan_tci;
- uint32_t status;
-
- /* Completion */
- union {
- struct {
- uint64_t rx_completion_tid;
- void *rx_completion_context;
- /* This is no longer used */
- pfn_on_send_rx_completion on_rx_completion;
- } rx;
- struct {
- uint64_t send_completion_tid;
- void *send_completion_context;
- /* Still used in netvsc and filter code */
- pfn_on_send_rx_completion on_send_completion;
- } send;
- } compl;
- uint32_t send_buf_section_idx;
- uint32_t send_buf_section_size;
-
- void *rndis_mesg;
+ uint16_t vlan_tci;
+ uint32_t status;
uint32_t tot_data_buf_len;
void *data;
- uint32_t gpa_cnt;
- struct vmbus_gpa gpa[NETVSC_PACKET_MAXPAGE];
} netvsc_packet;
typedef struct {
@@ -1216,6 +1193,9 @@ struct hn_tx_ring {
bus_dma_tag_t hn_tx_data_dtag;
uint64_t hn_csum_assist;
+ int hn_gpa_cnt;
+ struct vmbus_gpa hn_gpa[NETVSC_PACKET_MAXPAGE];
+
u_long hn_no_txdescs;
u_long hn_send_failed;
u_long hn_txdma_failed;
@@ -1269,13 +1249,15 @@ typedef struct hn_softc {
* Externs
*/
extern int hv_promisc_mode;
+struct hn_send_ctx;
void netvsc_linkstatus_callback(struct hn_softc *sc, uint32_t status);
netvsc_dev *hv_nv_on_device_add(struct hn_softc *sc,
void *additional_info, struct hn_rx_ring *rxr);
int hv_nv_on_device_remove(struct hn_softc *sc,
boolean_t destroy_channel);
-int hv_nv_on_send(struct vmbus_channel *chan, netvsc_packet *pkt);
+int hv_nv_on_send(struct vmbus_channel *chan, bool is_data_pkt,
+ struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt);
int hv_nv_get_next_send_section(netvsc_dev *net_dev);
void hv_nv_subchan_attach(struct vmbus_channel *chan,
struct hn_rx_ring *rxr);
Modified: stable/11/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
==============================================================================
--- stable/11/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Mon Oct 17 05:33:41 2016 (r307472)
+++ stable/11/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Mon Oct 17 05:37:22 2016 (r307473)
@@ -166,7 +166,7 @@ struct hn_txdesc {
struct hn_tx_ring *txr;
int refs;
uint32_t flags; /* HN_TXD_FLAG_ */
- netvsc_packet netvsc_pkt; /* XXX to be removed */
+ struct hn_send_ctx send_ctx;
bus_dmamap_t data_dmap;
@@ -781,14 +781,14 @@ hn_txeof(struct hn_tx_ring *txr)
}
static void
-hn_tx_done(struct vmbus_channel *chan, void *xpkt)
+hn_tx_done(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev,
+ struct vmbus_channel *chan, const struct nvsp_msg_ *msg __unused)
{
- netvsc_packet *packet = xpkt;
- struct hn_txdesc *txd;
+ struct hn_txdesc *txd = sndc->hn_cbarg;
struct hn_tx_ring *txr;
- txd = (struct hn_txdesc *)(uintptr_t)
- packet->compl.send.send_completion_tid;
+ if (sndc->hn_chim_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX)
+ hn_chim_free(net_dev, sndc->hn_chim_idx);
txr = txd->txr;
KASSERT(txr->hn_chan == chan,
@@ -835,16 +835,14 @@ hn_encap(struct hn_tx_ring *txr, struct
bus_dma_segment_t segs[HN_TX_DATA_SEGCNT_MAX];
int error, nsegs, i;
struct mbuf *m_head = *m_head0;
- netvsc_packet *packet;
rndis_msg *rndis_mesg;
rndis_packet *rndis_pkt;
rndis_per_packet_info *rppi;
struct rndis_hash_value *hash_value;
- uint32_t rndis_msg_size;
+ uint32_t rndis_msg_size, tot_data_buf_len, send_buf_section_idx;
+ int send_buf_section_size;
- packet = &txd->netvsc_pkt;
- packet->is_data_pkt = TRUE;
- packet->tot_data_buf_len = m_head->m_pkthdr.len;
+ tot_data_buf_len = m_head->m_pkthdr.len;
/*
* extension points to the area reserved for the
@@ -859,7 +857,7 @@ hn_encap(struct hn_tx_ring *txr, struct
rndis_pkt = &rndis_mesg->msg.packet;
rndis_pkt->data_offset = sizeof(rndis_packet);
- rndis_pkt->data_length = packet->tot_data_buf_len;
+ rndis_pkt->data_length = tot_data_buf_len;
rndis_pkt->per_pkt_info_offset = sizeof(rndis_packet);
rndis_msg_size = RNDIS_MESSAGE_SIZE(rndis_packet);
@@ -967,15 +965,14 @@ hn_encap(struct hn_tx_ring *txr, struct
}
}
- rndis_mesg->msg_len = packet->tot_data_buf_len + rndis_msg_size;
- packet->tot_data_buf_len = rndis_mesg->msg_len;
+ rndis_mesg->msg_len = tot_data_buf_len + rndis_msg_size;
+ tot_data_buf_len = rndis_mesg->msg_len;
/*
* Chimney send, if the packet could fit into one chimney buffer.
*/
- if (packet->tot_data_buf_len < txr->hn_tx_chimney_size) {
+ if (tot_data_buf_len < txr->hn_tx_chimney_size) {
netvsc_dev *net_dev = txr->hn_sc->net_dev;
- uint32_t send_buf_section_idx;
txr->hn_tx_chimney_tried++;
send_buf_section_idx =
@@ -990,10 +987,8 @@ hn_encap(struct hn_tx_ring *txr, struct
dest += rndis_msg_size;
m_copydata(m_head, 0, m_head->m_pkthdr.len, dest);
- packet->send_buf_section_idx = send_buf_section_idx;
- packet->send_buf_section_size =
- packet->tot_data_buf_len;
- packet->gpa_cnt = 0;
+ send_buf_section_size = tot_data_buf_len;
+ txr->hn_gpa_cnt = 0;
txr->hn_tx_chimney++;
goto done;
}
@@ -1019,19 +1014,19 @@ hn_encap(struct hn_tx_ring *txr, struct
}
*m_head0 = m_head;
- packet->gpa_cnt = nsegs + HV_RF_NUM_TX_RESERVED_PAGE_BUFS;
+ txr->hn_gpa_cnt = nsegs + HV_RF_NUM_TX_RESERVED_PAGE_BUFS;
/* send packet with page buffer */
- packet->gpa[0].gpa_page = atop(txd->rndis_msg_paddr);
- packet->gpa[0].gpa_ofs = txd->rndis_msg_paddr & PAGE_MASK;
- packet->gpa[0].gpa_len = rndis_msg_size;
+ txr->hn_gpa[0].gpa_page = atop(txd->rndis_msg_paddr);
+ txr->hn_gpa[0].gpa_ofs = txd->rndis_msg_paddr & PAGE_MASK;
+ txr->hn_gpa[0].gpa_len = rndis_msg_size;
/*
* Fill the page buffers with mbuf info starting at index
* HV_RF_NUM_TX_RESERVED_PAGE_BUFS.
*/
for (i = 0; i < nsegs; ++i) {
- struct vmbus_gpa *gpa = &packet->gpa[
+ struct vmbus_gpa *gpa = &txr->hn_gpa[
i + HV_RF_NUM_TX_RESERVED_PAGE_BUFS];
gpa->gpa_page = atop(segs[i].ds_addr);
@@ -1039,16 +1034,14 @@ hn_encap(struct hn_tx_ring *txr, struct
gpa->gpa_len = segs[i].ds_len;
}
- packet->send_buf_section_idx =
- NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
- packet->send_buf_section_size = 0;
+ send_buf_section_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
+ send_buf_section_size = 0;
done:
txd->m = m_head;
/* Set the completion routine */
- packet->compl.send.on_send_completion = hn_tx_done;
- packet->compl.send.send_completion_context = packet;
- packet->compl.send.send_completion_tid = (uint64_t)(uintptr_t)txd;
+ hn_send_ctx_init(&txd->send_ctx, hn_tx_done, txd,
+ send_buf_section_idx, send_buf_section_size);
return 0;
}
@@ -1068,7 +1061,8 @@ again:
* Make sure that txd is not freed before ETHER_BPF_MTAP.
*/
hn_txdesc_hold(txd);
- error = hv_nv_on_send(txr->hn_chan, &txd->netvsc_pkt);
+ error = hv_nv_on_send(txr->hn_chan, true, &txd->send_ctx,
+ txr->hn_gpa, txr->hn_gpa_cnt);
if (!error) {
ETHER_BPF_MTAP(ifp, txd->m);
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
Modified: stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.c
==============================================================================
--- stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.c Mon Oct 17 05:33:41 2016 (r307472)
+++ stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.c Mon Oct 17 05:37:22 2016 (r307473)
@@ -85,11 +85,17 @@ static int hv_rf_set_packet_filter(rndi
static int hv_rf_init_device(rndis_device *device);
static int hv_rf_open_device(rndis_device *device);
static int hv_rf_close_device(rndis_device *device);
-static void hv_rf_on_send_request_completion(struct vmbus_channel *, void *context);
-static void hv_rf_on_send_request_halt_completion(struct vmbus_channel *, void *context);
int
hv_rf_send_offload_request(struct hn_softc *sc,
rndis_offload_params *offloads);
+
+static void hn_rndis_sent_halt(struct hn_send_ctx *sndc,
+ struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
+ const struct nvsp_msg_ *msg);
+static void hn_rndis_sent_cb(struct hn_send_ctx *sndc,
+ struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
+ const struct nvsp_msg_ *msg);
+
/*
* Set the Per-Packet-Info with the specified type
*/
@@ -238,45 +244,36 @@ static int
hv_rf_send_request(rndis_device *device, rndis_request *request,
uint32_t message_type)
{
- int ret;
- netvsc_packet *packet;
netvsc_dev *net_dev = device->net_dev;
- int send_buf_section_idx;
+ uint32_t send_buf_section_idx, tot_data_buf_len;
+ struct vmbus_gpa gpa[2];
+ int gpa_cnt, send_buf_section_size;
+ hn_sent_callback_t cb;
/* Set up the packet to send it */
- packet = &request->pkt;
-
- packet->is_data_pkt = FALSE;
- packet->tot_data_buf_len = request->request_msg.msg_len;
- packet->gpa_cnt = 1;
-
- packet->gpa[0].gpa_page =
- hv_get_phys_addr(&request->request_msg) >> PAGE_SHIFT;
- packet->gpa[0].gpa_len = request->request_msg.msg_len;
- packet->gpa[0].gpa_ofs =
- (unsigned long)&request->request_msg & (PAGE_SIZE - 1);
-
- if (packet->gpa[0].gpa_ofs + packet->gpa[0].gpa_len > PAGE_SIZE) {
- packet->gpa_cnt = 2;
- packet->gpa[0].gpa_len = PAGE_SIZE - packet->gpa[0].gpa_ofs;
- packet->gpa[1].gpa_page =
- hv_get_phys_addr((char*)&request->request_msg +
- packet->gpa[0].gpa_len) >> PAGE_SHIFT;
- packet->gpa[1].gpa_ofs = 0;
- packet->gpa[1].gpa_len = request->request_msg.msg_len -
- packet->gpa[0].gpa_len;
- }
-
- packet->compl.send.send_completion_context = request; /* packet */
- if (message_type != REMOTE_NDIS_HALT_MSG) {
- packet->compl.send.on_send_completion =
- hv_rf_on_send_request_completion;
- } else {
- packet->compl.send.on_send_completion =
- hv_rf_on_send_request_halt_completion;
+ tot_data_buf_len = request->request_msg.msg_len;
+
+ gpa_cnt = 1;
+ gpa[0].gpa_page = hv_get_phys_addr(&request->request_msg) >> PAGE_SHIFT;
+ gpa[0].gpa_len = request->request_msg.msg_len;
+ gpa[0].gpa_ofs = (unsigned long)&request->request_msg & (PAGE_SIZE - 1);
+
+ if (gpa[0].gpa_ofs + gpa[0].gpa_len > PAGE_SIZE) {
+ gpa_cnt = 2;
+ gpa[0].gpa_len = PAGE_SIZE - gpa[0].gpa_ofs;
+ gpa[1].gpa_page =
+ hv_get_phys_addr((char*)&request->request_msg +
+ gpa[0].gpa_len) >> PAGE_SHIFT;
+ gpa[1].gpa_ofs = 0;
+ gpa[1].gpa_len = request->request_msg.msg_len - gpa[0].gpa_len;
}
- packet->compl.send.send_completion_tid = (unsigned long)device;
- if (packet->tot_data_buf_len < net_dev->send_section_size) {
+
+ if (message_type != REMOTE_NDIS_HALT_MSG)
+ cb = hn_rndis_sent_cb;
+ else
+ cb = hn_rndis_sent_halt;
+
+ if (tot_data_buf_len < net_dev->send_section_size) {
send_buf_section_idx = hv_nv_get_next_send_section(net_dev);
if (send_buf_section_idx !=
NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
@@ -284,20 +281,20 @@ hv_rf_send_request(rndis_device *device,
send_buf_section_idx * net_dev->send_section_size);
memcpy(dest, &request->request_msg, request->request_msg.msg_len);
- packet->send_buf_section_idx = send_buf_section_idx;
- packet->send_buf_section_size = packet->tot_data_buf_len;
- packet->gpa_cnt = 0;
+ send_buf_section_size = tot_data_buf_len;
+ gpa_cnt = 0;
goto sendit;
}
/* Failed to allocate chimney send buffer; move on */
}
- packet->send_buf_section_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
- packet->send_buf_section_size = 0;
+ send_buf_section_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
+ send_buf_section_size = 0;
sendit:
- ret = hv_nv_on_send(device->net_dev->sc->hn_prichan, packet);
-
- return (ret);
+ hn_send_ctx_init(&request->send_ctx, cb, request,
+ send_buf_section_idx, send_buf_section_size);
+ return hv_nv_on_send(device->net_dev->sc->hn_prichan, false,
+ &request->send_ctx, gpa, gpa_cnt);
}
/*
@@ -1059,6 +1056,7 @@ int
hv_rf_on_device_add(struct hn_softc *sc, void *additl_info,
int nchan, struct hn_rx_ring *rxr)
{
+ struct hn_send_ctx sndc;
int ret;
netvsc_dev *net_dev;
rndis_device *rndis_dev;
@@ -1165,9 +1163,10 @@ hv_rf_on_device_add(struct hn_softc *sc,
init_pkt->msgs.vers_5_msgs.subchannel_request.num_subchannels =
net_dev->num_channel - 1;
+ hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL);
ret = vmbus_chan_send(sc->hn_prichan,
VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
- init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt);
+ init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc);
if (ret != 0) {
device_printf(dev, "Fail to allocate subchannel\n");
goto out;
@@ -1238,23 +1237,22 @@ hv_rf_on_close(struct hn_softc *sc)
return (hv_rf_close_device((rndis_device *)net_dev->extension));
}
-/*
- * RNDIS filter on send request completion callback
- */
-static void
-hv_rf_on_send_request_completion(struct vmbus_channel *chan __unused,
- void *context __unused)
+static void
+hn_rndis_sent_cb(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev,
+ struct vmbus_channel *chan __unused, const struct nvsp_msg_ *msg __unused)
{
+ if (sndc->hn_chim_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX)
+ hn_chim_free(net_dev, sndc->hn_chim_idx);
}
-/*
- * RNDIS filter on send request (halt only) completion callback
- */
-static void
-hv_rf_on_send_request_halt_completion(struct vmbus_channel *chan __unused,
- void *context)
+static void
+hn_rndis_sent_halt(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev,
+ struct vmbus_channel *chan __unused, const struct nvsp_msg_ *msg __unused)
{
- rndis_request *request = context;
+ rndis_request *request = sndc->hn_cbarg;
+
+ if (sndc->hn_chim_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX)
+ hn_chim_free(net_dev, sndc->hn_chim_idx);
/*
* Notify hv_rf_halt_device() about halt completion.
Modified: stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.h
==============================================================================
--- stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.h Mon Oct 17 05:33:41 2016 (r307472)
+++ stable/11/sys/dev/hyperv/netvsc/hv_rndis_filter.h Mon Oct 17 05:37:22 2016 (r307473)
@@ -33,6 +33,7 @@
#include <sys/param.h>
#include <net/ethernet.h>
+#include <dev/hyperv/netvsc/if_hnvar.h>
/*
* Defines
@@ -75,7 +76,7 @@ typedef struct rndis_request_ {
uint8_t buf_resp[PAGE_SIZE];
/* Simplify allocation by having a netvsc packet inline */
- netvsc_packet pkt;
+ struct hn_send_ctx send_ctx;
/*
* The max request size is sizeof(rndis_msg) + PAGE_SIZE.
Copied: stable/11/sys/dev/hyperv/netvsc/if_hnvar.h (from r303901, head/sys/dev/hyperv/netvsc/if_hnvar.h)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ stable/11/sys/dev/hyperv/netvsc/if_hnvar.h Mon Oct 17 05:37:22 2016 (r307473, copy of r303901, head/sys/dev/hyperv/netvsc/if_hnvar.h)
@@ -0,0 +1,83 @@
+/*-
+ * Copyright (c) 2016 Microsoft Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice unmodified, this list of conditions, and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _IF_HNVAR_H_
+#define _IF_HNVAR_H_
+
+#include <sys/param.h>
+#include <dev/hyperv/netvsc/hv_net_vsc.h>
+
+struct netvsc_dev_;
+struct nvsp_msg_;
+
+struct vmbus_channel;
+struct hn_send_ctx;
+
+typedef void (*hn_sent_callback_t)
+ (struct hn_send_ctx *, struct netvsc_dev_ *,
+ struct vmbus_channel *, const struct nvsp_msg_ *);
+
+struct hn_send_ctx {
+ hn_sent_callback_t hn_cb;
+ void *hn_cbarg;
+ uint32_t hn_chim_idx;
+ int hn_chim_sz;
+};
+
+#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \
+{ \
+ .hn_cb = cb, \
+ .hn_cbarg = cbarg, \
+ .hn_chim_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX, \
+ .hn_chim_sz = 0 \
+}
+
+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)
+{
+ 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,
+ NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX, 0);
+}
+
+void hn_nvs_sent_wakeup(struct hn_send_ctx *sndc,
+ struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
+ const struct nvsp_msg_ *msg);
+void hn_chim_free(struct netvsc_dev_ *net_dev, uint32_t chim_idx);
+
+#endif /* !_IF_HNVAR_H_ */
More information about the svn-src-stable-11
mailing list