diff options
author | Wei Liu <wei.liu@kernel.org> | 2021-02-15 10:44:58 +0000 |
---|---|---|
committer | Wei Liu <wei.liu@kernel.org> | 2021-02-15 10:49:11 +0000 |
commit | 3019270282a175defc02c8331786c73e082cd2a8 (patch) | |
tree | 13a9b1c1be5030db044227dc12ff0b074443326d /drivers/hv | |
parent | fb5ef35165a37ca63ef0227657eabd06f0a39cf9 (diff) | |
download | lwn-3019270282a175defc02c8331786c73e082cd2a8.tar.gz lwn-3019270282a175defc02c8331786c73e082cd2a8.zip |
Revert "Drivers: hv: vmbus: Copy packets sent by Hyper-V out of the ring buffer"
This reverts commit a8c3209998afb5c4941b49e35b513cea9050cb4a.
It is reported that the said commit caused regression in netvsc.
Reported-by: Andrea Parri (Microsoft) <parri.andrea@gmail.com>
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Diffstat (limited to 'drivers/hv')
-rw-r--r-- | drivers/hv/channel.c | 9 | ||||
-rw-r--r-- | drivers/hv/hv_fcopy.c | 1 | ||||
-rw-r--r-- | drivers/hv/hv_kvp.c | 1 | ||||
-rw-r--r-- | drivers/hv/hyperv_vmbus.h | 2 | ||||
-rw-r--r-- | drivers/hv/ring_buffer.c | 82 |
5 files changed, 15 insertions, 80 deletions
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 9aa789e5f22b..0bd202de7960 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -597,15 +597,12 @@ static int __vmbus_open(struct vmbus_channel *newchannel, newchannel->onchannel_callback = onchannelcallback; newchannel->channel_callback_context = context; - if (!newchannel->max_pkt_size) - newchannel->max_pkt_size = VMBUS_DEFAULT_MAX_PKT_SIZE; - - err = hv_ringbuffer_init(&newchannel->outbound, page, send_pages, 0); + err = hv_ringbuffer_init(&newchannel->outbound, page, send_pages); if (err) goto error_clean_ring; - err = hv_ringbuffer_init(&newchannel->inbound, &page[send_pages], - recv_pages, newchannel->max_pkt_size); + err = hv_ringbuffer_init(&newchannel->inbound, + &page[send_pages], recv_pages); if (err) goto error_clean_ring; diff --git a/drivers/hv/hv_fcopy.c b/drivers/hv/hv_fcopy.c index 660036da7449..59ce85e00a02 100644 --- a/drivers/hv/hv_fcopy.c +++ b/drivers/hv/hv_fcopy.c @@ -349,7 +349,6 @@ int hv_fcopy_init(struct hv_util_service *srv) { recv_buffer = srv->recv_buffer; fcopy_transaction.recv_channel = srv->channel; - fcopy_transaction.recv_channel->max_pkt_size = HV_HYP_PAGE_SIZE * 2; /* * When this driver loads, the user level daemon that diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index c698592b83e4..b49962d312ce 100644 --- a/drivers/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c @@ -757,7 +757,6 @@ hv_kvp_init(struct hv_util_service *srv) { recv_buffer = srv->recv_buffer; kvp_transaction.recv_channel = srv->channel; - kvp_transaction.recv_channel->max_pkt_size = HV_HYP_PAGE_SIZE * 4; /* * When this driver loads, the user level daemon that diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index 42f3d9d123a1..9416e09ebd58 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -174,7 +174,7 @@ extern int hv_synic_cleanup(unsigned int cpu); void hv_ringbuffer_pre_init(struct vmbus_channel *channel); int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, - struct page *pages, u32 pagecnt, u32 max_pkt_size); + struct page *pages, u32 pagecnt); void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info); diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c index 29e90477363a..35833d4d1a1d 100644 --- a/drivers/hv/ring_buffer.c +++ b/drivers/hv/ring_buffer.c @@ -190,7 +190,7 @@ void hv_ringbuffer_pre_init(struct vmbus_channel *channel) /* Initialize the ring buffer. */ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, - struct page *pages, u32 page_cnt, u32 max_pkt_size) + struct page *pages, u32 page_cnt) { int i; struct page **pages_wraparound; @@ -232,14 +232,6 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, sizeof(struct hv_ring_buffer); ring_info->priv_read_index = 0; - /* Initialize buffer that holds copies of incoming packets */ - if (max_pkt_size) { - ring_info->pkt_buffer = kzalloc(max_pkt_size, GFP_KERNEL); - if (!ring_info->pkt_buffer) - return -ENOMEM; - ring_info->pkt_buffer_size = max_pkt_size; - } - spin_lock_init(&ring_info->ring_lock); return 0; @@ -252,9 +244,6 @@ void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info) vunmap(ring_info->ring_buffer); ring_info->ring_buffer = NULL; mutex_unlock(&ring_info->ring_buffer_mutex); - - kfree(ring_info->pkt_buffer); - ring_info->pkt_buffer_size = 0; } /* Write to the ring buffer. */ @@ -396,7 +385,7 @@ int hv_ringbuffer_read(struct vmbus_channel *channel, memcpy(buffer, (const char *)desc + offset, packetlen); /* Advance ring index to next packet descriptor */ - __hv_pkt_iter_next(channel, desc, true); + __hv_pkt_iter_next(channel, desc); /* Notify host of update */ hv_pkt_iter_close(channel); @@ -423,22 +412,6 @@ static u32 hv_pkt_iter_avail(const struct hv_ring_buffer_info *rbi) } /* - * Get first vmbus packet without copying it out of the ring buffer - */ -struct vmpacket_descriptor *hv_pkt_iter_first_raw(struct vmbus_channel *channel) -{ - struct hv_ring_buffer_info *rbi = &channel->inbound; - - hv_debug_delay_test(channel, MESSAGE_DELAY); - - if (hv_pkt_iter_avail(rbi) < sizeof(struct vmpacket_descriptor)) - return NULL; - - return (struct vmpacket_descriptor *)(hv_get_ring_buffer(rbi) + rbi->priv_read_index); -} -EXPORT_SYMBOL_GPL(hv_pkt_iter_first_raw); - -/* * Get first vmbus packet from ring buffer after read_index * * If ring buffer is empty, returns NULL and no other action needed. @@ -446,49 +419,17 @@ EXPORT_SYMBOL_GPL(hv_pkt_iter_first_raw); struct vmpacket_descriptor *hv_pkt_iter_first(struct vmbus_channel *channel) { struct hv_ring_buffer_info *rbi = &channel->inbound; - struct vmpacket_descriptor *desc, *desc_copy; - u32 bytes_avail, pkt_len, pkt_offset; + struct vmpacket_descriptor *desc; - desc = hv_pkt_iter_first_raw(channel); - if (!desc) + hv_debug_delay_test(channel, MESSAGE_DELAY); + if (hv_pkt_iter_avail(rbi) < sizeof(struct vmpacket_descriptor)) return NULL; - bytes_avail = min(rbi->pkt_buffer_size, hv_pkt_iter_avail(rbi)); - - /* - * Ensure the compiler does not use references to incoming Hyper-V values (which - * could change at any moment) when reading local variables later in the code - */ - pkt_len = READ_ONCE(desc->len8) << 3; - pkt_offset = READ_ONCE(desc->offset8) << 3; - - /* - * If pkt_len is invalid, set it to the smaller of hv_pkt_iter_avail() and - * rbi->pkt_buffer_size - */ - if (pkt_len < sizeof(struct vmpacket_descriptor) || pkt_len > bytes_avail) - pkt_len = bytes_avail; - - /* - * If pkt_offset is invalid, arbitrarily set it to - * the size of vmpacket_descriptor - */ - if (pkt_offset < sizeof(struct vmpacket_descriptor) || pkt_offset > pkt_len) - pkt_offset = sizeof(struct vmpacket_descriptor); - - /* Copy the Hyper-V packet out of the ring buffer */ - desc_copy = (struct vmpacket_descriptor *)rbi->pkt_buffer; - memcpy(desc_copy, desc, pkt_len); - - /* - * Hyper-V could still change len8 and offset8 after the earlier read. - * Ensure that desc_copy has legal values for len8 and offset8 that - * are consistent with the copy we just made - */ - desc_copy->len8 = pkt_len >> 3; - desc_copy->offset8 = pkt_offset >> 3; + desc = hv_get_ring_buffer(rbi) + rbi->priv_read_index; + if (desc) + prefetch((char *)desc + (desc->len8 << 3)); - return desc_copy; + return desc; } EXPORT_SYMBOL_GPL(hv_pkt_iter_first); @@ -500,8 +441,7 @@ EXPORT_SYMBOL_GPL(hv_pkt_iter_first); */ struct vmpacket_descriptor * __hv_pkt_iter_next(struct vmbus_channel *channel, - const struct vmpacket_descriptor *desc, - bool copy) + const struct vmpacket_descriptor *desc) { struct hv_ring_buffer_info *rbi = &channel->inbound; u32 packetlen = desc->len8 << 3; @@ -514,7 +454,7 @@ __hv_pkt_iter_next(struct vmbus_channel *channel, rbi->priv_read_index -= dsize; /* more data? */ - return copy ? hv_pkt_iter_first(channel) : hv_pkt_iter_first_raw(channel); + return hv_pkt_iter_first(channel); } EXPORT_SYMBOL_GPL(__hv_pkt_iter_next); |