From: Andrea Parri <parri.andrea@gmail.com>
To: Yanming Liu <yanminglr@gmail.com>
Cc: linux-hyperv@vger.kernel.org,
Andres Beltran <lkmlabelt@gmail.com>,
Dexuan Cui <decui@microsoft.com>, Wei Liu <wei.liu@kernel.org>,
Stephen Hemminger <sthemmin@microsoft.com>,
Haiyang Zhang <haiyangz@microsoft.com>,
"K. Y. Srinivasan" <kys@microsoft.com>,
Michael Kelley <mikelley@microsoft.com>
Subject: Re: [PATCH] hv: account for packet descriptor in maximum packet size
Date: Tue, 14 Dec 2021 03:06:58 +0100 [thread overview]
Message-ID: <20211214020658.GA439610@anparri> (raw)
In-Reply-To: <CAH+BkoF-Y55MCSoFes3QYJqXEEH3ZsjHMjmtrKmN3UHv9S_0iw@mail.gmail.com>
> Truncated packet:
> module("hv_vmbus").statement("hv_pkt_iter_first@drivers/hv/ring_buffer.c:457"):
> desc->offset8 = 2, desc->len8 = 514, rbi->pkt_buffer_size = 4096
> module("hv_vmbus").statement("hv_ringbuffer_read@drivers/hv/ring_buffer.c:382"):
> desc->offset8 = 2, desc->len8 = 512
> balloon_onchannelcallback: recvlen = 4080, dm_hdr->type = 8
>
> First garbage packet:
> module("hv_vmbus").statement("hv_pkt_iter_first@drivers/hv/ring_buffer.c:457"):
> desc->offset8 = 21, desc->len8 = 16640, rbi->pkt_buffer_size = 4096
> module("hv_vmbus").statement("hv_ringbuffer_read@drivers/hv/ring_buffer.c:382"):
> desc->offset8 = 21, desc->len8 = 512
> balloon_onchannelcallback: recvlen = 3928, dm_hdr->type = 63886
>
> The trace proved my hypothesis above.
Thanks for the confirmation.
(Back to "how to fix this" now.) I think that the patch properly addresses
the "mismatch" between the (maximum) size of the receive buffer (bufferlen
in vmbus_recvpacket()) and max_pkt_size:
We've discussed hv_ballon in some:
1) drivers/hv/hv_balloon.c:balloon_onchannelcallback()
(bufferlen = HV_HYP_PAGE_SIZE, max_pkt_size = VMBUS_DEFAULT_MAX_PKT_SIZE)
But I understand that the same mismatch is present *and addressed by your
patch in the following cases:
2) drivers/hv/hv_util.c:{shutdown,timesync,heartbeat}_onchannelcallback()
(bufferlen = HV_HYP_PAGE_SIZE, max_pkt_size = VMBUS_DEFAULT_MAX_PKT_SIZE)
3) drivers/hv/hv_fcopy.c:hv_fcopy_onchannelcallback()
(bufferlen = 2 * HV_HYP_PAGE_SIZE, max_pkt_size = 2 * HV_HYP_PAGE_SIZE)
4) drivers/hv/hv_snapshot.c:hv_vss_onchannelcallback()
(bufferlen= 2 * HV_HYP_PAGE_SIZE, max_pkt_size= 2 * HV_HYP_PAGE_SIZE)
5) drivers/hv/hv_kvp.c:hv_kvp_onchannelcallback()
(bufferlen= 4 * HV_HYP_PAGE_SIZE, max_pkt_size= 4 * HV_HYP_PAGE_SIZE)
In fact, IIUC, similar considerations would apply to hv_fb and hv_drm *if
it were not for the fact that those drivers seem to have bogus values for
max_pkt_size:
6) drivers/video/fbdev/hyperv_fb.c
(bufferlen = MAX_VMBUS_PKT_SIZE, max_pkt_size=VMBUS_DEFAULT_MAX_PKT_SIZE)
7) drivers/gpu/drm/hyperv/hyperv_drm_proto.c
(bufferlen = MAX_VMBUS_PKT_SIZE, max_pkt_size=VMBUS_DEFAULT_MAX_PKT_SIZE)
So, IIUC, some separate patch is needed in order to "adjust" those values
(say, by appropriately setting max_pkt_size in synthvid_connect_vsp() and
in hyperv_connect_vsp()), but I digress.
Other comments on your patch:
a) You mentioned the problem that "pkt_offset may not match the packet
descriptor size". I think this is a real problem. To address this
problem, we can *presumably consider HV_HYP_PAGE_SIZE to be a valid
upper bound for pkt_offset (and sizeof(struct vmpacket_descriptor))
*and increase the value of max_pkt_size by HV_HYP_PAGE_SIZE (rather
than sizeof(struct vmpacket_descriptor)), like in:
@@ -256,6 +256,7 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
/* Initialize buffer that holds copies of incoming packets */
if (max_pkt_size) {
+ max_pkt_size += HV_HYP_PAGE_SIZE;
ring_info->pkt_buffer = kzalloc(max_pkt_size, GFP_KERNEL);
if (!ring_info->pkt_buffer)
return -ENOMEM;
b) We may then want to "enforce"/check that that bound on pkt_offset,
pkt_offset <= HV_HYP_PAGE_SIZE,
is met by adding a corresponding check to the (previously discussed)
validation of pkt_offset included in hv_pkt_iter_first(), say:
@@ -498,7 +498,8 @@ struct vmpacket_descriptor *hv_pkt_iter_first(struct vmbus_channel *channel)
* 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)
+ if (pkt_offset < sizeof(struct vmpacket_descriptor) || pkt_offset > pkt_len ||
+ pkt_offset > HV_HYP_PAGE_SIZE)
pkt_offset = sizeof(struct vmpacket_descriptor);
/* Copy the Hyper-V packet out of the ring buffer */
While there (since I have noticed that such validation as well the
validation on pkt_len in hv_pkt_iter_first() tend to be the object
of a somehow recurring discussion ;/), I wouldn't mind to add some
"explicit" debug, pr_err_ratelimited() say, there.
c) Last but not least, I'd recommend to pair the above changes or any
other change with some inline explanation/comments; these comments
could be snippets from an (updated) patch description for example.
Andrea
next prev parent reply other threads:[~2021-12-14 2:07 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-12 12:13 [PATCH] hv: account for packet descriptor in maximum packet size Yanming Liu
2021-12-13 1:47 ` Andrea Parri
2021-12-13 6:44 ` Yanming Liu
2021-12-13 17:01 ` Yanming Liu
2021-12-14 2:06 ` Andrea Parri [this message]
2021-12-14 4:28 ` Andrea Parri
2021-12-14 16:28 ` Yanming Liu
2021-12-14 21:36 ` Andrea Parri
2021-12-15 12:30 ` Yanming Liu
2021-12-15 14:05 ` Andrea Parri
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211214020658.GA439610@anparri \
--to=parri.andrea@gmail.com \
--cc=decui@microsoft.com \
--cc=haiyangz@microsoft.com \
--cc=kys@microsoft.com \
--cc=linux-hyperv@vger.kernel.org \
--cc=lkmlabelt@gmail.com \
--cc=mikelley@microsoft.com \
--cc=sthemmin@microsoft.com \
--cc=wei.liu@kernel.org \
--cc=yanminglr@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox