* [PATCH v2,net] hv_netvsc: Fix tx_table init in rndis_set_subchannel()
From: Haiyang Zhang @ 2019-12-11 22:26 UTC (permalink / raw)
To: sashal, linux-hyperv, netdev
Cc: haiyangz, kys, sthemmin, olaf, vkuznets, davem, linux-kernel
Host can provide send indirection table messages anytime after RSS is
enabled by calling rndis_filter_set_rss_param(). So the host provided
table values may be overwritten by the initialization in
rndis_set_subchannel().
To prevent this problem, move the tx_table initialization before calling
rndis_filter_set_rss_param().
Fixes: a6fb6aa3cfa9 ("hv_netvsc: Set tx_table to equal weight after subchannels open")
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
drivers/net/hyperv/rndis_filter.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 206b4e7..05bc5ec8 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -1171,6 +1171,9 @@ int rndis_set_subchannel(struct net_device *ndev,
wait_event(nvdev->subchan_open,
atomic_read(&nvdev->open_chn) == nvdev->num_chn);
+ for (i = 0; i < VRSS_SEND_TAB_SIZE; i++)
+ ndev_ctx->tx_table[i] = i % nvdev->num_chn;
+
/* ignore failures from setting rss parameters, still have channels */
if (dev_info)
rndis_filter_set_rss_param(rdev, dev_info->rss_key);
@@ -1180,9 +1183,6 @@ int rndis_set_subchannel(struct net_device *ndev,
netif_set_real_num_tx_queues(ndev, nvdev->num_chn);
netif_set_real_num_rx_queues(ndev, nvdev->num_chn);
- for (i = 0; i < VRSS_SEND_TAB_SIZE; i++)
- ndev_ctx->tx_table[i] = i % nvdev->num_chn;
-
return 0;
}
--
1.8.3.1
^ permalink raw reply related
* RE: [EXTERNAL] Re: [RFC PATCH 3/4] Hyper-V/Balloon: Call add_memory() with dm_device.ha_lock.
From: Tianyu Lan @ 2019-12-12 8:24 UTC (permalink / raw)
To: vkuznets, lantianyu1986@gmail.com, KY Srinivasan, Haiyang Zhang,
Stephen Hemminger, sashal@kernel.org, Michael Kelley
Cc: linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org,
eric.devolder@oracle.com
In-Reply-To: <87pnguc3ln.fsf@vitty.brq.redhat.com>
Hi Vitaly:
Thanks for your review.
> From: Vitaly Kuznetsov <vkuznets@redhat.com>
> > From: Tianyu Lan <Tianyu.Lan@microsoft.com>
> > @@ -771,8 +767,13 @@ static void hv_online_page(struct page *pg,
> unsigned int order)
> > struct hv_hotadd_state *has;
> > unsigned long flags;
> > unsigned long pfn = page_to_pfn(pg);
> > + int unlocked;
> > +
> > + if (dm_device.lock_thread != current) {
>
> With lock_thread checking you're trying to protect against taking the spinlock
> twice (when this is called from add_memory()) but why not just check that
> spin_is_locked() AND we sit on the same CPU as the VMBus channel
> attached to the balloon device?
Yes, that's another approach.
>
> > + spin_lock_irqsave(&dm_device.ha_lock, flags);
> > + unlocked = 1;
> > + }
>
> We set unlocked to '1' when we're actually locked, aren't we?
The "unlocked" means ha_lock isn't hold before calling hv_online_page().
>
> >
> > - spin_lock_irqsave(&dm_device.ha_lock, flags);
> > list_for_each_entry(has, &dm_device.ha_region_list, list) {
> > /* The page belongs to a different HAS. */
> > if ((pfn < has->start_pfn) ||
> > @@ -782,7 +783,9 @@ static void hv_online_page(struct page *pg,
> unsigned int order)
> > hv_bring_pgs_online(has, pfn, 1UL << order);
> > break;
> > }
> > - spin_unlock_irqrestore(&dm_device.ha_lock, flags);
> > +
> > + if (unlocked)
> > + spin_unlock_irqrestore(&dm_device.ha_lock, flags);
> > }
> >
> > static int pfn_covered(unsigned long start_pfn, unsigned long
> > pfn_cnt) @@ -860,6 +863,7 @@ static unsigned long
> handle_pg_range(unsigned long pg_start,
> > pg_start);
> >
> > spin_lock_irqsave(&dm_device.ha_lock, flags);
> > + dm_device.lock_thread = current;
> > list_for_each_entry(has, &dm_device.ha_region_list, list) {
> > /*
> > * If the pfn range we are dealing with is not in the current
> @@
> > -912,9 +916,7 @@ static unsigned long handle_pg_range(unsigned long
> pg_start,
> > } else {
> > pfn_cnt = size;
> > }
> > - spin_unlock_irqrestore(&dm_device.ha_lock, flags);
> > hv_mem_hot_add(has->ha_end_pfn, size, pfn_cnt,
> has);
> > - spin_lock_irqsave(&dm_device.ha_lock, flags);
>
> Apart from the deadlock you mention in the commit message, add_memory
> does lock_device_hotplug()/unlock_device_hotplug() which is a mutex. If
> I'm not mistaken you now take the mutext under a spinlock
> (&dm_device.ha_lock). Not good.
Yes, you are right. I missed this. I will try other way. Nice catch. Thanks.
>
>
> > }
> > /*
> > * If we managed to online any pages that were given to us,
> @@
> > -923,6 +925,7 @@ static unsigned long handle_pg_range(unsigned long
> pg_start,
> > res = has->covered_end_pfn - old_covered_state;
> > break;
> > }
> > + dm_device.lock_thread = NULL;
> > spin_unlock_irqrestore(&dm_device.ha_lock, flags);
> >
> > return res;
>
> --
> Vitaly
^ permalink raw reply
* Re: BUG: corrupted list in __dentry_kill (2)
From: syzbot @ 2019-12-12 11:35 UTC (permalink / raw)
To: a, alex.aring, allison, andrew, andy, ap420073, ast, ast,
b.a.t.m.a.n, bpf, bridge, cleech, daniel, davem, dsa, dsahern,
dvyukov, f.fainelli, fw, gregkh, haiyangz, hawk, hdanton, idosch,
info, j.vosburgh, j, jakub.kicinski, jhs, jiri, jiri,
johan.hedberg, johannes.berg, john.fastabend, john.hurley, jwi,
kafai, kstewart, kvalo, kys, linux-bluetooth, linux-fsdevel,
linux-hams, linux-hyperv, linux-kernel, linux-ppp, linux-wireless,
linux-wpan, liuhangbin, marcel
In-Reply-To: <000000000000b6b03205997b71cf@google.com>
syzbot has bisected this bug to:
commit ab92d68fc22f9afab480153bd82a20f6e2533769
Author: Taehee Yoo <ap420073@gmail.com>
Date: Mon Oct 21 18:47:51 2019 +0000
net: core: add generic lockdep keys
bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=12d37cb6e00000
start commit: 938f49c8 Add linux-next specific files for 20191211
git tree: linux-next
final crash: https://syzkaller.appspot.com/x/report.txt?x=11d37cb6e00000
console output: https://syzkaller.appspot.com/x/log.txt?x=16d37cb6e00000
kernel config: https://syzkaller.appspot.com/x/.config?x=96834c884ba7bb81
dashboard link: https://syzkaller.appspot.com/bug?extid=31043da7725b6ec210f1
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=12dc83dae00000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=16ac8396e00000
Reported-by: syzbot+31043da7725b6ec210f1@syzkaller.appspotmail.com
Fixes: ab92d68fc22f ("net: core: add generic lockdep keys")
For information about bisection process see: https://goo.gl/tpsmEJ#bisection
^ permalink raw reply
* RE: [EXTERNAL] Re: [RFC PATCH 4/4] x86/Hyper-V: Add memory hot remove function
From: Tianyu Lan @ 2019-12-12 13:37 UTC (permalink / raw)
To: vkuznets, lantianyu1986@gmail.com, KY Srinivasan, Haiyang Zhang,
Stephen Hemminger, sashal@kernel.org, Michael Kelley
Cc: linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org,
eric.devolder@oracle.com
In-Reply-To: <87mubyc367.fsf@vitty.brq.redhat.com>
> From: Vitaly Kuznetsov <vkuznets@redhat.com>
>
> > From: Tianyu Lan <Tianyu.Lan@microsoft.com>
> >
> > @@ -376,6 +391,27 @@ struct dm_hot_add_response {
> > __u32 result;
> > } __packed;
> >
> > +struct dm_hot_remove {
> > + struct dm_header hdr;
> > + __u32 virtual_node;
> > + __u32 page_count;
> > + __u32 qos_flags;
> > + __u32 reservedZ;
> > +} __packed;
> > +
> > +struct dm_hot_remove_response {
> > + struct dm_header hdr;
> > + __u32 result;
> > + __u32 range_count;
> > + __u64 more_pages:1;
> > + __u64 reservedz:63;
> > + union dm_mem_page_range range_array[]; } __packed;
> > +
> > +#define DM_REMOVE_QOS_LARGE (1 << 0)
> > +#define DM_REMOVE_QOS_LOCAL (1 << 1)
> > +#define DM_REMOVE_QoS_MASK (0x3)
>
> Capitalize 'QoS' to make it match previous two lines please.
>
Yes, Will fix it.
> > +
> > /*
> > * Types of information sent from host to the guest.
> > */
> > @@ -457,6 +493,13 @@ struct hot_add_wrk {
> > struct work_struct wrk;
> > };
> >
> > +struct hot_remove_wrk {
> > + __u32 virtual_node;
> > + __u32 page_count;
> > + __u32 qos_flags;
> > + struct work_struct wrk;
> > +};
> > +
> > static bool hot_add = true;
> > static bool do_hot_add;
> > /*
> > @@ -489,6 +532,7 @@ enum hv_dm_state {
> > DM_BALLOON_UP,
> > DM_BALLOON_DOWN,
> > DM_HOT_ADD,
> > + DM_HOT_REMOVE,
> > DM_INIT_ERROR
> > };
> >
> > @@ -515,11 +559,13 @@ struct hv_dynmem_device {
> > * State to manage the ballooning (up) operation.
> > */
> > struct balloon_state balloon_wrk;
> > + struct balloon_state unballoon_wrk;
> >
> > /*
> > * State to execute the "hot-add" operation.
>
> This comment is stale now.
>
Will update. Thanks.
> > */
> > struct hot_add_wrk ha_wrk;
> > + struct hot_remove_wrk hr_wrk;
>
> Do we actually want to work struct and all the problems with their
> serialization? Can we get away with one?
I think it's possible to just use one work to handle all kind of msgs
with a work struct which contains parameters for all dm msgs and identify
the msg type in the work callback function.
^ permalink raw reply
* Re: [PATCH v2,net] hv_netvsc: Fix tx_table init in rndis_set_subchannel()
From: Jakub Kicinski @ 2019-12-14 19:30 UTC (permalink / raw)
To: Haiyang Zhang
Cc: sashal, linux-hyperv, netdev, kys, sthemmin, olaf, vkuznets,
davem, linux-kernel
In-Reply-To: <1576103187-2681-1-git-send-email-haiyangz@microsoft.com>
On Wed, 11 Dec 2019 14:26:27 -0800, Haiyang Zhang wrote:
> Host can provide send indirection table messages anytime after RSS is
> enabled by calling rndis_filter_set_rss_param(). So the host provided
> table values may be overwritten by the initialization in
> rndis_set_subchannel().
>
> To prevent this problem, move the tx_table initialization before calling
> rndis_filter_set_rss_param().
>
> Fixes: a6fb6aa3cfa9 ("hv_netvsc: Set tx_table to equal weight after subchannels open")
> Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Applied, but there are two more problems with this code:
- you should not reset the indirection table if it was configured by
the user to something other than the default (use the
netif_is_rxfh_configured() helper to check for that)
- you should use the ethtool_rxfh_indir_default() wrapper
Please fix the former problem in the net tree, and after net is merged
into linux/master and net-next in a week or two please follow up with
the fix for the latter for net-next.
> diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
> index 206b4e7..05bc5ec8 100644
> --- a/drivers/net/hyperv/rndis_filter.c
> +++ b/drivers/net/hyperv/rndis_filter.c
> @@ -1171,6 +1171,9 @@ int rndis_set_subchannel(struct net_device *ndev,
> wait_event(nvdev->subchan_open,
> atomic_read(&nvdev->open_chn) == nvdev->num_chn);
>
> + for (i = 0; i < VRSS_SEND_TAB_SIZE; i++)
> + ndev_ctx->tx_table[i] = i % nvdev->num_chn;
> +
> /* ignore failures from setting rss parameters, still have channels */
> if (dev_info)
> rndis_filter_set_rss_param(rdev, dev_info->rss_key);
> @@ -1180,9 +1183,6 @@ int rndis_set_subchannel(struct net_device *ndev,
> netif_set_real_num_tx_queues(ndev, nvdev->num_chn);
> netif_set_real_num_rx_queues(ndev, nvdev->num_chn);
>
> - for (i = 0; i < VRSS_SEND_TAB_SIZE; i++)
> - ndev_ctx->tx_table[i] = i % nvdev->num_chn;
> -
> return 0;
> }
>
^ permalink raw reply
* RE: [PATCH v2,net] hv_netvsc: Fix tx_table init in rndis_set_subchannel()
From: Haiyang Zhang @ 2019-12-15 16:38 UTC (permalink / raw)
To: Jakub Kicinski
Cc: sashal@kernel.org, linux-hyperv@vger.kernel.org,
netdev@vger.kernel.org, KY Srinivasan, Stephen Hemminger,
olaf@aepfle.de, vkuznets, davem@davemloft.net,
linux-kernel@vger.kernel.org
In-Reply-To: <20191214113025.363f21e2@cakuba.netronome.com>
> -----Original Message-----
> From: Jakub Kicinski <jakub.kicinski@netronome.com>
> Sent: Saturday, December 14, 2019 2:30 PM
> To: Haiyang Zhang <haiyangz@microsoft.com>
> Cc: sashal@kernel.org; linux-hyperv@vger.kernel.org; netdev@vger.kernel.org;
> KY Srinivasan <kys@microsoft.com>; Stephen Hemminger
> <sthemmin@microsoft.com>; olaf@aepfle.de; vkuznets
> <vkuznets@redhat.com>; davem@davemloft.net; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v2,net] hv_netvsc: Fix tx_table init in rndis_set_subchannel()
>
> On Wed, 11 Dec 2019 14:26:27 -0800, Haiyang Zhang wrote:
> > Host can provide send indirection table messages anytime after RSS is
> > enabled by calling rndis_filter_set_rss_param(). So the host provided
> > table values may be overwritten by the initialization in
> > rndis_set_subchannel().
> >
> > To prevent this problem, move the tx_table initialization before calling
> > rndis_filter_set_rss_param().
> >
> > Fixes: a6fb6aa3cfa9 ("hv_netvsc: Set tx_table to equal weight after
> subchannels open")
> > Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
>
> Applied, but there are two more problems with this code:
> - you should not reset the indirection table if it was configured by
> the user to something other than the default (use the
> netif_is_rxfh_configured() helper to check for that)
For Send indirection table (tx_table) ethtool doesn't have the option
to set it, and it's usually provided by the host. So we always initialize
it...
But, yes, for Receive indirection table (rx_table), I will make a fix, so
it will be set to default only for new devices, or changing the number
of channels; otherwise it will remain the same during operations like
changing MTU, ringparam.
> - you should use the ethtool_rxfh_indir_default() wrapper
For rx_table, we already use it:
rndis_device->rx_table[i] = ethtool_rxfh_indir_default(
For tx_table, I know it's the same operation (%, mod), but this wrapper
function's name is for rx_table. Should we use it for tx_table too?
>
> Please fix the former problem in the net tree, and after net is merged
> into linux/master and net-next in a week or two please follow up with
> the fix for the latter for net-next.
Sure.
Thanks,
- Haiyang
^ permalink raw reply
* Re: [PATCH v2,net] hv_netvsc: Fix tx_table init in rndis_set_subchannel()
From: Stephen Hemminger @ 2019-12-15 17:11 UTC (permalink / raw)
To: Haiyang Zhang
Cc: Jakub Kicinski, sashal@kernel.org, linux-hyperv@vger.kernel.org,
netdev@vger.kernel.org, KY Srinivasan, Stephen Hemminger,
olaf@aepfle.de, vkuznets, davem@davemloft.net,
linux-kernel@vger.kernel.org
In-Reply-To: <MN2PR21MB1375F30B3BEEF42DFDB3D39ECA560@MN2PR21MB1375.namprd21.prod.outlook.com>
On Sun, 15 Dec 2019 16:38:00 +0000
Haiyang Zhang <haiyangz@microsoft.com> wrote:
> > -----Original Message-----
> > From: Jakub Kicinski <jakub.kicinski@netronome.com>
> > Sent: Saturday, December 14, 2019 2:30 PM
> > To: Haiyang Zhang <haiyangz@microsoft.com>
> > Cc: sashal@kernel.org; linux-hyperv@vger.kernel.org; netdev@vger.kernel.org;
> > KY Srinivasan <kys@microsoft.com>; Stephen Hemminger
> > <sthemmin@microsoft.com>; olaf@aepfle.de; vkuznets
> > <vkuznets@redhat.com>; davem@davemloft.net; linux-kernel@vger.kernel.org
> > Subject: Re: [PATCH v2,net] hv_netvsc: Fix tx_table init in rndis_set_subchannel()
> >
> > On Wed, 11 Dec 2019 14:26:27 -0800, Haiyang Zhang wrote:
> > > Host can provide send indirection table messages anytime after RSS is
> > > enabled by calling rndis_filter_set_rss_param(). So the host provided
> > > table values may be overwritten by the initialization in
> > > rndis_set_subchannel().
> > >
> > > To prevent this problem, move the tx_table initialization before calling
> > > rndis_filter_set_rss_param().
> > >
> > > Fixes: a6fb6aa3cfa9 ("hv_netvsc: Set tx_table to equal weight after
> > subchannels open")
> > > Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> >
> > Applied, but there are two more problems with this code:
> > - you should not reset the indirection table if it was configured by
> > the user to something other than the default (use the
> > netif_is_rxfh_configured() helper to check for that)
>
> For Send indirection table (tx_table) ethtool doesn't have the option
> to set it, and it's usually provided by the host. So we always initialize
> it...
> But, yes, for Receive indirection table (rx_table), I will make a fix, so
> it will be set to default only for new devices, or changing the number
> of channels; otherwise it will remain the same during operations like
> changing MTU, ringparam.
>
>
> > - you should use the ethtool_rxfh_indir_default() wrapper
> For rx_table, we already use it:
> rndis_device->rx_table[i] = ethtool_rxfh_indir_default(
> For tx_table, I know it's the same operation (%, mod), but this wrapper
> function's name is for rx_table. Should we use it for tx_table too?
>
> >
> > Please fix the former problem in the net tree, and after net is merged
> > into linux/master and net-next in a week or two please follow up with
> > the fix for the latter for net-next.
>
> Sure.
>
> Thanks,
> - Haiyang
>
As Haiyang said, this send indirection table is unique to Hyper-V it is not part of
any of the other device models. It is not supported by ethtool. It would not be
appropriate to repurpose the existing indirection tool; the device already uses
the receive indirection table for RSS.
^ permalink raw reply
* Re: [PATCH v2,net] hv_netvsc: Fix tx_table init in rndis_set_subchannel()
From: Jakub Kicinski @ 2019-12-15 18:52 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Haiyang Zhang, sashal@kernel.org, linux-hyperv@vger.kernel.org,
netdev@vger.kernel.org, KY Srinivasan, Stephen Hemminger,
olaf@aepfle.de, vkuznets, davem@davemloft.net,
linux-kernel@vger.kernel.org
In-Reply-To: <20191215091120.24e581e1@hermes.lan>
On Sun, 15 Dec 2019 09:11:20 -0800, Stephen Hemminger wrote:
> > > On Wed, 11 Dec 2019 14:26:27 -0800, Haiyang Zhang wrote:
> > > > Host can provide send indirection table messages anytime after RSS is
> > > > enabled by calling rndis_filter_set_rss_param(). So the host provided
> > > > table values may be overwritten by the initialization in
> > > > rndis_set_subchannel().
> > > >
> > > > To prevent this problem, move the tx_table initialization before calling
> > > > rndis_filter_set_rss_param().
> > > >
> > > > Fixes: a6fb6aa3cfa9 ("hv_netvsc: Set tx_table to equal weight after
> > > subchannels open")
> > > > Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> > >
> > > Applied, but there are two more problems with this code:
> > > - you should not reset the indirection table if it was configured by
> > > the user to something other than the default (use the
> > > netif_is_rxfh_configured() helper to check for that)
> >
> > For Send indirection table (tx_table) ethtool doesn't have the option
> > to set it, and it's usually provided by the host. So we always initialize
> > it...
> > But, yes, for Receive indirection table (rx_table), I will make a fix, so
> > it will be set to default only for new devices, or changing the number
> > of channels; otherwise it will remain the same during operations like
> > changing MTU, ringparam.
Thank you!
> > > - you should use the ethtool_rxfh_indir_default() wrapper
> > For rx_table, we already use it:
> > rndis_device->rx_table[i] = ethtool_rxfh_indir_default(
> > For tx_table, I know it's the same operation (%, mod), but this wrapper
> > function's name is for rx_table. Should we use it for tx_table too?
> >
> > >
> > > Please fix the former problem in the net tree, and after net is merged
> > > into linux/master and net-next in a week or two please follow up with
> > > the fix for the latter for net-next.
> >
> > Sure.
> >
> > Thanks,
> > - Haiyang
> >
> As Haiyang said, this send indirection table is unique to Hyper-V it is not part of
> any of the other device models. It is not supported by ethtool. It would not be
> appropriate to repurpose the existing indirection tool; the device already uses
> the receive indirection table for RSS.
I see, I got confused by the use of the term RSS.
^ permalink raw reply
* [RFC 0/6] vDSO support for Hyper-V guest on ARM64
From: Boqun Feng @ 2019-12-16 0:19 UTC (permalink / raw)
To: linux-hyperv, linux-arm-kernel, linux-kernel
Cc: Michael Kelley, Vincenzo Frascino, Catalin Marinas, Will Deacon,
Thomas Gleixner, K. Y. Srinivasan, Haiyang Zhang,
Stephen Hemminger, Sasha Levin, xen-devel, Stefano Stabellini,
Boqun Feng
Hi,
This is the RFC patchset for vDSO support in ARM64 Hyper-V guest. To
test it, Michael's ARM64 support patchset:
https://lore.kernel.org/linux-arm-kernel/1570129355-16005-1-git-send-email-mikelley@microsoft.com/
is needed.
Similar as x86, Hyper-V on ARM64 use a TSC page for guests to read
the virtualized hardware timer, this TSC page is read-only for the
guests, so could be used for vDSO data page. And the vDSO (userspace)
code could use the same code for timer reading as kernel, since
they read the same TSC page.
This patchset therefore extends ARM64's __vsdo_init() to allow multiple
data pages and introduces the vclock_mode concept similar to x86 to
allow different platforms (bare-metal, Hyper-V, etc.) to switch to
different __arch_get_hw_counter() implementations. The rest of this
patchset does the necessary setup for Hyper-V guests: mapping tsc page,
enabling userspace to read cntvct, etc. to enable vDSO.
This patchset consists of 6 patches:
patch #1 allows hv_get_raw_timer() definition to be overridden for
userspace and kernel to share the same hv_read_tsc_page() definition.
patch #2 extends ARM64 to support multiple vDSO data pages.
patch #3 introduces vclock_mode similiar to x86 to allow different
__arch_get_hw_counter() implementations for different clocksources.
patch #4 maps Hyper-V TSC page into vDSO data page.
patch #5 allows userspace to read cntvct, so that userspace can
efficiently read the clocksource.
patch #6 enables the vDSO for ARM64 Hyper-V guest.
The whole patchset is based on v5.5-rc1 plus Michael's ARM64 support
patchset, and I've done a few tests with:
https://github.com/nlynch-mentor/vdsotest
Comments and suggestions are welcome!
Regards,
Boqun
^ permalink raw reply
* [RFC 2/6] arm64: vdso: Add support for multiple vDSO data pages
From: Boqun Feng @ 2019-12-16 0:19 UTC (permalink / raw)
To: linux-hyperv, linux-arm-kernel, linux-kernel
Cc: Michael Kelley, Vincenzo Frascino, Catalin Marinas, Will Deacon,
Thomas Gleixner, K. Y. Srinivasan, Haiyang Zhang,
Stephen Hemminger, Sasha Levin, xen-devel, Stefano Stabellini,
Boqun Feng, Matteo Croce
In-Reply-To: <20191216001922.23008-1-boqun.feng@gmail.com>
Split __vdso_abi::vdso_pages into nr_vdso_{data,code}_pages, so that
__setup_additional_pages() could work with multiple vDSO data pages with
the setup from __vdso_init().
Multiple vDSO data pages are required when running in a virtualized
environment, where the cycles read from cntvct at userspace need to
be adjusted with some data from a page maintained by the hypervisor. For
example, the TSC page in Hyper-V.
This is a prerequisite for vDSO support in ARM64 on Hyper-V.
Signed-off-by: Boqun Feng (Microsoft) <boqun.feng@gmail.com>
---
arch/arm64/kernel/vdso.c | 43 ++++++++++++++++++++++++----------------
1 file changed, 26 insertions(+), 17 deletions(-)
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 354b11e27c07..b9b5ec7a3084 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -50,7 +50,8 @@ struct __vdso_abi {
const char *name;
const char *vdso_code_start;
const char *vdso_code_end;
- unsigned long vdso_pages;
+ unsigned long nr_vdso_data_pages;
+ unsigned long nr_vdso_code_pages;
/* Data Mapping */
struct vm_special_mapping *dm;
/* Code Mapping */
@@ -101,6 +102,8 @@ static int __vdso_init(enum arch_vdso_type arch_index)
{
int i;
struct page **vdso_pagelist;
+ struct page **vdso_code_pagelist;
+ unsigned long nr_vdso_pages;
unsigned long pfn;
if (memcmp(vdso_lookup[arch_index].vdso_code_start, "\177ELF", 4)) {
@@ -108,14 +111,18 @@ static int __vdso_init(enum arch_vdso_type arch_index)
return -EINVAL;
}
- vdso_lookup[arch_index].vdso_pages = (
+ vdso_lookup[arch_index].nr_vdso_data_pages = 1;
+
+ vdso_lookup[arch_index].nr_vdso_code_pages = (
vdso_lookup[arch_index].vdso_code_end -
vdso_lookup[arch_index].vdso_code_start) >>
PAGE_SHIFT;
- /* Allocate the vDSO pagelist, plus a page for the data. */
- vdso_pagelist = kcalloc(vdso_lookup[arch_index].vdso_pages + 1,
- sizeof(struct page *),
+ nr_vdso_pages = vdso_lookup[arch_index].nr_vdso_data_pages +
+ vdso_lookup[arch_index].nr_vdso_code_pages;
+
+ /* Allocate the vDSO pagelist. */
+ vdso_pagelist = kcalloc(nr_vdso_pages, sizeof(struct page *),
GFP_KERNEL);
if (vdso_pagelist == NULL)
return -ENOMEM;
@@ -123,15 +130,17 @@ static int __vdso_init(enum arch_vdso_type arch_index)
/* Grab the vDSO data page. */
vdso_pagelist[0] = phys_to_page(__pa_symbol(vdso_data));
-
/* Grab the vDSO code pages. */
pfn = sym_to_pfn(vdso_lookup[arch_index].vdso_code_start);
- for (i = 0; i < vdso_lookup[arch_index].vdso_pages; i++)
- vdso_pagelist[i + 1] = pfn_to_page(pfn + i);
+ vdso_code_pagelist = vdso_pagelist +
+ vdso_lookup[arch_index].nr_vdso_data_pages;
+
+ for (i = 0; i < vdso_lookup[arch_index].nr_vdso_code_pages; i++)
+ vdso_code_pagelist[i] = pfn_to_page(pfn + i);
- vdso_lookup[arch_index].dm->pages = &vdso_pagelist[0];
- vdso_lookup[arch_index].cm->pages = &vdso_pagelist[1];
+ vdso_lookup[arch_index].dm->pages = vdso_pagelist;
+ vdso_lookup[arch_index].cm->pages = vdso_code_pagelist;
return 0;
}
@@ -141,26 +150,26 @@ static int __setup_additional_pages(enum arch_vdso_type arch_index,
struct linux_binprm *bprm,
int uses_interp)
{
- unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
+ unsigned long vdso_base, vdso_text_len, vdso_data_len;
void *ret;
- vdso_text_len = vdso_lookup[arch_index].vdso_pages << PAGE_SHIFT;
- /* Be sure to map the data page */
- vdso_mapping_len = vdso_text_len + PAGE_SIZE;
+ vdso_data_len = vdso_lookup[arch_index].nr_vdso_data_pages << PAGE_SHIFT;
+ vdso_text_len = vdso_lookup[arch_index].nr_vdso_code_pages << PAGE_SHIFT;
- vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
+ vdso_base = get_unmapped_area(NULL, 0,
+ vdso_data_len + vdso_text_len, 0, 0);
if (IS_ERR_VALUE(vdso_base)) {
ret = ERR_PTR(vdso_base);
goto up_fail;
}
- ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE,
+ ret = _install_special_mapping(mm, vdso_base, vdso_data_len,
VM_READ|VM_MAYREAD,
vdso_lookup[arch_index].dm);
if (IS_ERR(ret))
goto up_fail;
- vdso_base += PAGE_SIZE;
+ vdso_base += vdso_data_len;
mm->context.vdso = (void *)vdso_base;
ret = _install_special_mapping(mm, vdso_base, vdso_text_len,
VM_READ|VM_EXEC|
--
2.24.0
^ permalink raw reply related
* [RFC 1/6] arm64: hyperv: Allow hv_get_raw_timer() definition to be overridden
From: Boqun Feng @ 2019-12-16 0:19 UTC (permalink / raw)
To: linux-hyperv, linux-arm-kernel, linux-kernel
Cc: Michael Kelley, Vincenzo Frascino, Catalin Marinas, Will Deacon,
Thomas Gleixner, K. Y. Srinivasan, Haiyang Zhang,
Stephen Hemminger, Sasha Levin, xen-devel, Stefano Stabellini,
Boqun Feng
In-Reply-To: <20191216001922.23008-1-boqun.feng@gmail.com>
In order to support vDSO, hv_read_tsc_page() should be able to be called
from userspace if tsc page mapped. As a result, hv_get_raw_timer(),
called by hv_read_tsc_page() requires to be called by both kernel and
vDSO. Currently, it's defined as arch_timer_read_counter(), which is a
function pointer initialized (using a kernel address) by the arch timer
driver, therefore not usable in vDSO.
Fix this by allowing a previous definition to override the default one,
so that in vDSO code, we can define it as a function callable in
userspace.
Signed-off-by: Boqun Feng (Microsoft) <boqun.feng@gmail.com>
---
arch/arm64/include/asm/mshyperv.h | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/mshyperv.h b/arch/arm64/include/asm/mshyperv.h
index a8468a611912..9cc4aeddf2d0 100644
--- a/arch/arm64/include/asm/mshyperv.h
+++ b/arch/arm64/include/asm/mshyperv.h
@@ -97,8 +97,15 @@ extern void hv_get_vpreg_128(u32 reg, struct hv_get_vp_register_output *result);
#define hv_disable_stimer0_percpu_irq(irq) disable_percpu_irq(irq)
#endif
-/* ARM64 specific code to read the hardware clock */
+/*
+ * ARM64 specific code to read the hardware clock.
+ *
+ * This could be used in both kernel space and userspace (vDSO), so make it
+ * possible for a previous definition to override the default one.
+ */
+#ifndef hv_get_raw_timer
#define hv_get_raw_timer() arch_timer_read_counter()
+#endif
#include <asm-generic/mshyperv.h>
--
2.24.0
^ permalink raw reply related
* [RFC 3/6] arm/arm64: clocksource: Introduce vclock_mode
From: Boqun Feng @ 2019-12-16 0:19 UTC (permalink / raw)
To: linux-hyperv, linux-arm-kernel, linux-kernel
Cc: Michael Kelley, Vincenzo Frascino, Catalin Marinas, Will Deacon,
Thomas Gleixner, K. Y. Srinivasan, Haiyang Zhang,
Stephen Hemminger, Sasha Levin, xen-devel, Stefano Stabellini,
Boqun Feng, Russell King, Mark Rutland, Marc Zyngier,
Daniel Lezcano, Allison Randal, Enrico Weigelt,
Geert Uytterhoeven, Huacai Chen
In-Reply-To: <20191216001922.23008-1-boqun.feng@gmail.com>
Similar to x86, use a vclock_mode in arch_clocksource_data to differ
clocksoures use different read function in vDSO.
No functional changes, only preparation for support vDSO in ARM64 on
Hyper-V.
Note: the changes for arm are only because arm and arm64 share the same
code in the arch timer driver and require arch_clocksource_data having
the same field.
Signed-off-by: Boqun Feng (Microsoft) <boqun.feng@gmail.com>
---
arch/arm/include/asm/clocksource.h | 6 +++++-
arch/arm/kernel/vdso.c | 1 -
arch/arm64/include/asm/clocksource.h | 6 +++++-
arch/arm64/include/asm/mshyperv.h | 2 +-
arch/arm64/include/asm/vdso/compat_gettimeofday.h | 5 +++--
arch/arm64/include/asm/vdso/gettimeofday.h | 5 +++--
arch/arm64/include/asm/vdso/vsyscall.h | 4 +---
drivers/clocksource/arm_arch_timer.c | 8 ++++----
8 files changed, 22 insertions(+), 15 deletions(-)
diff --git a/arch/arm/include/asm/clocksource.h b/arch/arm/include/asm/clocksource.h
index 0b350a7e26f3..017c5ab6e587 100644
--- a/arch/arm/include/asm/clocksource.h
+++ b/arch/arm/include/asm/clocksource.h
@@ -1,8 +1,12 @@
#ifndef _ASM_CLOCKSOURCE_H
#define _ASM_CLOCKSOURCE_H
+#define VCLOCK_NONE 0 /* No vDSO clock available. */
+#define VCLOCK_CNTVCT 1 /* vDSO should use cntvcnt */
+#define VCLOCK_MAX 1
+
struct arch_clocksource_data {
- bool vdso_direct; /* Usable for direct VDSO access? */
+ int vclock_mode;
};
#endif
diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
index c89ac1b9d28b..09e46ec420fe 100644
--- a/arch/arm/kernel/vdso.c
+++ b/arch/arm/kernel/vdso.c
@@ -263,4 +263,3 @@ void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
if (!IS_ERR(vma))
mm->context.vdso = addr;
}
-
diff --git a/arch/arm64/include/asm/clocksource.h b/arch/arm64/include/asm/clocksource.h
index 0ece64a26c8c..fbe80057468c 100644
--- a/arch/arm64/include/asm/clocksource.h
+++ b/arch/arm64/include/asm/clocksource.h
@@ -2,8 +2,12 @@
#ifndef _ASM_CLOCKSOURCE_H
#define _ASM_CLOCKSOURCE_H
+#define VCLOCK_NONE 0 /* No vDSO clock available. */
+#define VCLOCK_CNTVCT 1 /* vDSO should use cntvcnt */
+#define VCLOCK_MAX 1
+
struct arch_clocksource_data {
- bool vdso_direct; /* Usable for direct VDSO access? */
+ int vclock_mode;
};
#endif
diff --git a/arch/arm64/include/asm/mshyperv.h b/arch/arm64/include/asm/mshyperv.h
index 9cc4aeddf2d0..0afb00e3501d 100644
--- a/arch/arm64/include/asm/mshyperv.h
+++ b/arch/arm64/include/asm/mshyperv.h
@@ -90,7 +90,7 @@ extern void hv_get_vpreg_128(u32 reg, struct hv_get_vp_register_output *result);
#define hv_set_reference_tsc(val) \
hv_set_vpreg(HV_REGISTER_REFERENCE_TSC, val)
#define hv_set_clocksource_vdso(val) \
- ((val).archdata.vdso_direct = false)
+ ((val).archdata.vclock_mode = VCLOCK_NONE)
#if IS_ENABLED(CONFIG_HYPERV)
#define hv_enable_stimer0_percpu_irq(irq) enable_percpu_irq(irq, 0)
diff --git a/arch/arm64/include/asm/vdso/compat_gettimeofday.h b/arch/arm64/include/asm/vdso/compat_gettimeofday.h
index c50ee1b7d5cd..630d04c3c92e 100644
--- a/arch/arm64/include/asm/vdso/compat_gettimeofday.h
+++ b/arch/arm64/include/asm/vdso/compat_gettimeofday.h
@@ -8,6 +8,7 @@
#ifndef __ASSEMBLY__
#include <asm/unistd.h>
+#include <asm/clocksource.h>
#include <uapi/linux/time.h>
#include <asm/vdso/compat_barrier.h>
@@ -117,10 +118,10 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
u64 res;
/*
- * clock_mode == 0 implies that vDSO are enabled otherwise
+ * clock_mode == VCLOCK_NONE implies that vDSO are disabled so
* fallback on syscall.
*/
- if (clock_mode)
+ if (clock_mode == VCLOCK_NONE)
return __VDSO_USE_SYSCALL;
/*
diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h
index b08f476b72b4..e6e3fe0488c7 100644
--- a/arch/arm64/include/asm/vdso/gettimeofday.h
+++ b/arch/arm64/include/asm/vdso/gettimeofday.h
@@ -8,6 +8,7 @@
#ifndef __ASSEMBLY__
#include <asm/unistd.h>
+#include <asm/clocksource.h>
#include <uapi/linux/time.h>
#define __VDSO_USE_SYSCALL ULLONG_MAX
@@ -71,10 +72,10 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
u64 res;
/*
- * clock_mode == 0 implies that vDSO are enabled otherwise
+ * clock_mode == VCLOCK_NONE implies that vDSO are disabled so
* fallback on syscall.
*/
- if (clock_mode)
+ if (clock_mode == VCLOCK_NONE)
return __VDSO_USE_SYSCALL;
/*
diff --git a/arch/arm64/include/asm/vdso/vsyscall.h b/arch/arm64/include/asm/vdso/vsyscall.h
index 0c20a7c1bee5..07f78b0da498 100644
--- a/arch/arm64/include/asm/vdso/vsyscall.h
+++ b/arch/arm64/include/asm/vdso/vsyscall.h
@@ -24,9 +24,7 @@ struct vdso_data *__arm64_get_k_vdso_data(void)
static __always_inline
int __arm64_get_clock_mode(struct timekeeper *tk)
{
- u32 use_syscall = !tk->tkr_mono.clock->archdata.vdso_direct;
-
- return use_syscall;
+ return tk->tkr_mono.clock->archdata.vclock_mode;
}
#define __arch_get_clock_mode __arm64_get_clock_mode
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 9a5464c625b4..9b8d4d00b53b 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -69,7 +69,7 @@ static enum arch_timer_ppi_nr arch_timer_uses_ppi = ARCH_TIMER_VIRT_PPI;
static bool arch_timer_c3stop;
static bool arch_timer_mem_use_virtual;
static bool arch_counter_suspend_stop;
-static bool vdso_default = true;
+static int vdso_default = VCLOCK_CNTVCT;
static cpumask_t evtstrm_available = CPU_MASK_NONE;
static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM);
@@ -560,8 +560,8 @@ void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa
* change both the default value and the vdso itself.
*/
if (wa->read_cntvct_el0) {
- clocksource_counter.archdata.vdso_direct = false;
- vdso_default = false;
+ clocksource_counter.archdata.vclock_mode = VCLOCK_NONE;
+ vdso_default = VCLOCK_NONE;
}
}
@@ -979,7 +979,7 @@ static void __init arch_counter_register(unsigned type)
}
arch_timer_read_counter = rd;
- clocksource_counter.archdata.vdso_direct = vdso_default;
+ clocksource_counter.archdata.vclock_mode = vdso_default;
} else {
arch_timer_read_counter = arch_counter_get_cntvct_mem;
}
--
2.24.0
^ permalink raw reply related
* [RFC 4/6] arm64: vdso: hyperv: Map tsc page into vDSO if enabled
From: Boqun Feng @ 2019-12-16 0:19 UTC (permalink / raw)
To: linux-hyperv, linux-arm-kernel, linux-kernel
Cc: Michael Kelley, Vincenzo Frascino, Catalin Marinas, Will Deacon,
Thomas Gleixner, K. Y. Srinivasan, Haiyang Zhang,
Stephen Hemminger, Sasha Levin, xen-devel, Stefano Stabellini,
Boqun Feng, Matteo Croce, Allison Randal, Greg Kroah-Hartman,
Alexios Zavras
In-Reply-To: <20191216001922.23008-1-boqun.feng@gmail.com>
On Hyper-V, a tsc page has the data for adjusting cntvct numbers to
clocksource cycles, and that's how Hyper-V guest kernel reads the
clocksource. In order to allow userspace to read the same clocksource
directly, the tsc page has to been mapped into userspace via vDSO.
Use the framework for vDSO set-up in __vdso_init() to do this.
Note: if HYPERV_TIMER=y but the kernel is using other clocksource or
doesn't have the hyperv timer clocksource, tsc page will still be mapped
into userspace.
Signed-off-by: Boqun Feng (Microsoft) <boqun.feng@gmail.com>
---
arch/arm64/kernel/vdso.c | 12 ++++++++++++
arch/arm64/kernel/vdso/vdso.lds.S | 12 +++++++++++-
2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index b9b5ec7a3084..18a634987bdc 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -9,6 +9,7 @@
#include <linux/cache.h>
#include <linux/clocksource.h>
+#include <clocksource/hyperv_timer.h>
#include <linux/elf.h>
#include <linux/err.h>
#include <linux/errno.h>
@@ -105,14 +106,22 @@ static int __vdso_init(enum arch_vdso_type arch_index)
struct page **vdso_code_pagelist;
unsigned long nr_vdso_pages;
unsigned long pfn;
+ struct ms_hyperv_tsc_page *tsc_page;
+ int tsc_page_idx;
if (memcmp(vdso_lookup[arch_index].vdso_code_start, "\177ELF", 4)) {
pr_err("vDSO is not a valid ELF object!\n");
return -EINVAL;
}
+ /* One vDSO data page */
vdso_lookup[arch_index].nr_vdso_data_pages = 1;
+ /* Grab the Hyper-V tsc page, if enabled, add one more page */
+ tsc_page = hv_get_tsc_page();
+ if (tsc_page)
+ tsc_page_idx = vdso_lookup[arch_index].nr_vdso_data_pages++;
+
vdso_lookup[arch_index].nr_vdso_code_pages = (
vdso_lookup[arch_index].vdso_code_end -
vdso_lookup[arch_index].vdso_code_start) >>
@@ -130,6 +139,9 @@ static int __vdso_init(enum arch_vdso_type arch_index)
/* Grab the vDSO data page. */
vdso_pagelist[0] = phys_to_page(__pa_symbol(vdso_data));
+ if (tsc_page)
+ vdso_pagelist[tsc_page_idx] = phys_to_page(__pa(tsc_page));
+
/* Grab the vDSO code pages. */
pfn = sym_to_pfn(vdso_lookup[arch_index].vdso_code_start);
diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vdso.lds.S
index 7ad2d3a0cd48..e40a1f5a6d30 100644
--- a/arch/arm64/kernel/vdso/vdso.lds.S
+++ b/arch/arm64/kernel/vdso/vdso.lds.S
@@ -17,7 +17,17 @@ OUTPUT_ARCH(aarch64)
SECTIONS
{
- PROVIDE(_vdso_data = . - PAGE_SIZE);
+ /*
+ * vdso data pages:
+ * vdso data (1 page)
+ * hv tsc page (1 page if enabled)
+ */
+ PROVIDE(_vdso_data = _hvclock_page - PAGE_SIZE);
+#ifdef CONFIG_HYPERV_TIMER
+ PROVIDE(_hvclock_page = . - PAGE_SIZE);
+#else
+ PROVIDE(_hvclock_page = .);
+#endif
. = VDSO_LBASE + SIZEOF_HEADERS;
.hash : { *(.hash) } :text
--
2.24.0
^ permalink raw reply related
* [RFC 5/6] arm64: hyperv: Enable userspace to read cntvct
From: Boqun Feng @ 2019-12-16 0:19 UTC (permalink / raw)
To: linux-hyperv, linux-arm-kernel, linux-kernel
Cc: Michael Kelley, Vincenzo Frascino, Catalin Marinas, Will Deacon,
Thomas Gleixner, K. Y. Srinivasan, Haiyang Zhang,
Stephen Hemminger, Sasha Levin, xen-devel, Stefano Stabellini,
Boqun Feng
In-Reply-To: <20191216001922.23008-1-boqun.feng@gmail.com>
Since reading hyperv-timer clocksource requires reading cntvct,
userspace should be allowed to read it, otherwise reading cntvct will
result in traps, which makes vsyscall's cost similar compared to
syscall's.
So enable it on every cpu when a Hyper-V guest booting up.
Signed-off-by: Boqun Feng (Microsoft) <boqun.feng@gmail.com>
---
arch/arm64/hyperv/hv_init.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm64/hyperv/hv_init.c b/arch/arm64/hyperv/hv_init.c
index 86e4621d5885..1ea97ecfb143 100644
--- a/arch/arm64/hyperv/hv_init.c
+++ b/arch/arm64/hyperv/hv_init.c
@@ -27,6 +27,7 @@
#include <linux/sched_clock.h>
#include <asm-generic/bug.h>
#include <asm/hyperv-tlfs.h>
+#include <asm/arch_timer.h>
#include <asm/mshyperv.h>
#include <asm/sysreg.h>
#include <clocksource/hyperv_timer.h>
@@ -45,6 +46,7 @@ EXPORT_SYMBOL_GPL(hv_max_vp_index);
static int hv_cpu_init(unsigned int cpu)
{
u64 msr_vp_index;
+ u32 cntkctl;
hv_get_vp_index(msr_vp_index);
@@ -53,6 +55,11 @@ static int hv_cpu_init(unsigned int cpu)
if (msr_vp_index > hv_max_vp_index)
hv_max_vp_index = msr_vp_index;
+ /* Enable EL0 to access cntvct */
+ cntkctl = arch_timer_get_cntkctl();
+ cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN;
+ arch_timer_set_cntkctl(cntkctl);
+
return 0;
}
--
2.24.0
^ permalink raw reply related
* [RFC 6/6] arm64: hyperv: Enable vDSO
From: Boqun Feng @ 2019-12-16 0:19 UTC (permalink / raw)
To: linux-hyperv, linux-arm-kernel, linux-kernel
Cc: Michael Kelley, Vincenzo Frascino, Catalin Marinas, Will Deacon,
Thomas Gleixner, K. Y. Srinivasan, Haiyang Zhang,
Stephen Hemminger, Sasha Levin, xen-devel, Stefano Stabellini,
Boqun Feng
In-Reply-To: <20191216001922.23008-1-boqun.feng@gmail.com>
Similar to x86, add a new vclock_mode VCLOCK_HVCLOCK, and reuse the
hv_read_tsc_page() for userspace to read tsc page clocksource.
Signed-off-by: Boqun Feng (Microsoft) <boqun.feng@gmail.com>
---
arch/arm64/include/asm/clocksource.h | 3 ++-
arch/arm64/include/asm/mshyperv.h | 2 +-
arch/arm64/include/asm/vdso/gettimeofday.h | 19 +++++++++++++++++++
3 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/include/asm/clocksource.h b/arch/arm64/include/asm/clocksource.h
index fbe80057468c..c6acd45fe748 100644
--- a/arch/arm64/include/asm/clocksource.h
+++ b/arch/arm64/include/asm/clocksource.h
@@ -4,7 +4,8 @@
#define VCLOCK_NONE 0 /* No vDSO clock available. */
#define VCLOCK_CNTVCT 1 /* vDSO should use cntvcnt */
-#define VCLOCK_MAX 1
+#define VCLOCK_HVCLOCK 2 /* vDSO should use vread_hvclock() */
+#define VCLOCK_MAX 2
struct arch_clocksource_data {
int vclock_mode;
diff --git a/arch/arm64/include/asm/mshyperv.h b/arch/arm64/include/asm/mshyperv.h
index 0afb00e3501d..7c85dd816dca 100644
--- a/arch/arm64/include/asm/mshyperv.h
+++ b/arch/arm64/include/asm/mshyperv.h
@@ -90,7 +90,7 @@ extern void hv_get_vpreg_128(u32 reg, struct hv_get_vp_register_output *result);
#define hv_set_reference_tsc(val) \
hv_set_vpreg(HV_REGISTER_REFERENCE_TSC, val)
#define hv_set_clocksource_vdso(val) \
- ((val).archdata.vclock_mode = VCLOCK_NONE)
+ ((val).archdata.vclock_mode = VCLOCK_HVCLOCK)
#if IS_ENABLED(CONFIG_HYPERV)
#define hv_enable_stimer0_percpu_irq(irq) enable_percpu_irq(irq, 0)
diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h
index e6e3fe0488c7..7e689b903f4d 100644
--- a/arch/arm64/include/asm/vdso/gettimeofday.h
+++ b/arch/arm64/include/asm/vdso/gettimeofday.h
@@ -67,6 +67,20 @@ int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
return ret;
}
+#ifdef CONFIG_HYPERV_TIMER
+/* This will override the default hv_get_raw_timer() */
+#define hv_get_raw_timer() __arch_counter_get_cntvct()
+#include <clocksource/hyperv_timer.h>
+
+extern struct ms_hyperv_tsc_page
+_hvclock_page __attribute__((visibility("hidden")));
+
+static u64 vread_hvclock(void)
+{
+ return hv_read_tsc_page(&_hvclock_page);
+}
+#endif
+
static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
{
u64 res;
@@ -78,6 +92,11 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
if (clock_mode == VCLOCK_NONE)
return __VDSO_USE_SYSCALL;
+#ifdef CONFIG_HYPERV_TIMER
+ if (likely(clock_mode == VCLOCK_HVCLOCK))
+ return vread_hvclock();
+#endif
+
/*
* This isb() is required to prevent that the counter value
* is speculated.
--
2.24.0
^ permalink raw reply related
* Re: [RFC 6/6] arm64: hyperv: Enable vDSO
From: Vitaly Kuznetsov @ 2019-12-17 14:10 UTC (permalink / raw)
To: Boqun Feng
Cc: Michael Kelley, Vincenzo Frascino, Catalin Marinas, Will Deacon,
Thomas Gleixner, K. Y. Srinivasan, Haiyang Zhang,
Stephen Hemminger, Sasha Levin, xen-devel, Stefano Stabellini,
Boqun Feng, linux-hyperv, linux-arm-kernel, linux-kernel
In-Reply-To: <20191216001922.23008-7-boqun.feng@gmail.com>
Boqun Feng <boqun.feng@gmail.com> writes:
> Similar to x86, add a new vclock_mode VCLOCK_HVCLOCK, and reuse the
> hv_read_tsc_page() for userspace to read tsc page clocksource.
>
> Signed-off-by: Boqun Feng (Microsoft) <boqun.feng@gmail.com>
> ---
> arch/arm64/include/asm/clocksource.h | 3 ++-
> arch/arm64/include/asm/mshyperv.h | 2 +-
> arch/arm64/include/asm/vdso/gettimeofday.h | 19 +++++++++++++++++++
> 3 files changed, 22 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/include/asm/clocksource.h b/arch/arm64/include/asm/clocksource.h
> index fbe80057468c..c6acd45fe748 100644
> --- a/arch/arm64/include/asm/clocksource.h
> +++ b/arch/arm64/include/asm/clocksource.h
> @@ -4,7 +4,8 @@
>
> #define VCLOCK_NONE 0 /* No vDSO clock available. */
> #define VCLOCK_CNTVCT 1 /* vDSO should use cntvcnt */
> -#define VCLOCK_MAX 1
> +#define VCLOCK_HVCLOCK 2 /* vDSO should use vread_hvclock() */
> +#define VCLOCK_MAX 2
>
> struct arch_clocksource_data {
> int vclock_mode;
> diff --git a/arch/arm64/include/asm/mshyperv.h b/arch/arm64/include/asm/mshyperv.h
> index 0afb00e3501d..7c85dd816dca 100644
> --- a/arch/arm64/include/asm/mshyperv.h
> +++ b/arch/arm64/include/asm/mshyperv.h
> @@ -90,7 +90,7 @@ extern void hv_get_vpreg_128(u32 reg, struct hv_get_vp_register_output *result);
> #define hv_set_reference_tsc(val) \
> hv_set_vpreg(HV_REGISTER_REFERENCE_TSC, val)
> #define hv_set_clocksource_vdso(val) \
> - ((val).archdata.vclock_mode = VCLOCK_NONE)
> + ((val).archdata.vclock_mode = VCLOCK_HVCLOCK)
>
> #if IS_ENABLED(CONFIG_HYPERV)
> #define hv_enable_stimer0_percpu_irq(irq) enable_percpu_irq(irq, 0)
> diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h
> index e6e3fe0488c7..7e689b903f4d 100644
> --- a/arch/arm64/include/asm/vdso/gettimeofday.h
> +++ b/arch/arm64/include/asm/vdso/gettimeofday.h
> @@ -67,6 +67,20 @@ int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
> return ret;
> }
>
> +#ifdef CONFIG_HYPERV_TIMER
> +/* This will override the default hv_get_raw_timer() */
> +#define hv_get_raw_timer() __arch_counter_get_cntvct()
> +#include <clocksource/hyperv_timer.h>
> +
> +extern struct ms_hyperv_tsc_page
> +_hvclock_page __attribute__((visibility("hidden")));
> +
> +static u64 vread_hvclock(void)
> +{
> + return hv_read_tsc_page(&_hvclock_page);
> +}
> +#endif
The function is almost the same on x86 (&_hvclock_page ->
&hvclock_page), would it maybe make sense to move this to arch neutral
clocksource/hyperv_timer.h?
> +
> static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
> {
> u64 res;
> @@ -78,6 +92,11 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
> if (clock_mode == VCLOCK_NONE)
> return __VDSO_USE_SYSCALL;
>
> +#ifdef CONFIG_HYPERV_TIMER
> + if (likely(clock_mode == VCLOCK_HVCLOCK))
> + return vread_hvclock();
I'm not sure likely() is justified here: it'll make ALL builds which
enable CONFIG_HYPERV_TIMER (e.g. distro kernels) to prefer
VCLOCK_HVCLOCK, even if the kernel is not running on Hyper-V.
> +#endif
> +
> /*
> * This isb() is required to prevent that the counter value
> * is speculated.
--
Vitaly
^ permalink raw reply
* Re: [RFC 6/6] arm64: hyperv: Enable vDSO
From: Boqun Feng @ 2019-12-18 5:47 UTC (permalink / raw)
To: Vitaly Kuznetsov
Cc: Michael Kelley, Vincenzo Frascino, Catalin Marinas, Will Deacon,
Thomas Gleixner, K. Y. Srinivasan, Haiyang Zhang,
Stephen Hemminger, Sasha Levin, xen-devel, Stefano Stabellini,
linux-hyperv, linux-arm-kernel, linux-kernel
In-Reply-To: <87y2vb82lz.fsf@vitty.brq.redhat.com>
On Tue, Dec 17, 2019 at 03:10:16PM +0100, Vitaly Kuznetsov wrote:
> Boqun Feng <boqun.feng@gmail.com> writes:
>
> > Similar to x86, add a new vclock_mode VCLOCK_HVCLOCK, and reuse the
> > hv_read_tsc_page() for userspace to read tsc page clocksource.
> >
> > Signed-off-by: Boqun Feng (Microsoft) <boqun.feng@gmail.com>
> > ---
> > arch/arm64/include/asm/clocksource.h | 3 ++-
> > arch/arm64/include/asm/mshyperv.h | 2 +-
> > arch/arm64/include/asm/vdso/gettimeofday.h | 19 +++++++++++++++++++
> > 3 files changed, 22 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/clocksource.h b/arch/arm64/include/asm/clocksource.h
> > index fbe80057468c..c6acd45fe748 100644
> > --- a/arch/arm64/include/asm/clocksource.h
> > +++ b/arch/arm64/include/asm/clocksource.h
> > @@ -4,7 +4,8 @@
> >
> > #define VCLOCK_NONE 0 /* No vDSO clock available. */
> > #define VCLOCK_CNTVCT 1 /* vDSO should use cntvcnt */
> > -#define VCLOCK_MAX 1
> > +#define VCLOCK_HVCLOCK 2 /* vDSO should use vread_hvclock() */
> > +#define VCLOCK_MAX 2
> >
> > struct arch_clocksource_data {
> > int vclock_mode;
> > diff --git a/arch/arm64/include/asm/mshyperv.h b/arch/arm64/include/asm/mshyperv.h
> > index 0afb00e3501d..7c85dd816dca 100644
> > --- a/arch/arm64/include/asm/mshyperv.h
> > +++ b/arch/arm64/include/asm/mshyperv.h
> > @@ -90,7 +90,7 @@ extern void hv_get_vpreg_128(u32 reg, struct hv_get_vp_register_output *result);
> > #define hv_set_reference_tsc(val) \
> > hv_set_vpreg(HV_REGISTER_REFERENCE_TSC, val)
> > #define hv_set_clocksource_vdso(val) \
> > - ((val).archdata.vclock_mode = VCLOCK_NONE)
> > + ((val).archdata.vclock_mode = VCLOCK_HVCLOCK)
> >
> > #if IS_ENABLED(CONFIG_HYPERV)
> > #define hv_enable_stimer0_percpu_irq(irq) enable_percpu_irq(irq, 0)
> > diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h
> > index e6e3fe0488c7..7e689b903f4d 100644
> > --- a/arch/arm64/include/asm/vdso/gettimeofday.h
> > +++ b/arch/arm64/include/asm/vdso/gettimeofday.h
> > @@ -67,6 +67,20 @@ int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
> > return ret;
> > }
> >
> > +#ifdef CONFIG_HYPERV_TIMER
> > +/* This will override the default hv_get_raw_timer() */
> > +#define hv_get_raw_timer() __arch_counter_get_cntvct()
> > +#include <clocksource/hyperv_timer.h>
> > +
> > +extern struct ms_hyperv_tsc_page
> > +_hvclock_page __attribute__((visibility("hidden")));
> > +
> > +static u64 vread_hvclock(void)
> > +{
> > + return hv_read_tsc_page(&_hvclock_page);
> > +}
> > +#endif
>
> The function is almost the same on x86 (&_hvclock_page ->
> &hvclock_page), would it maybe make sense to move this to arch neutral
> clocksource/hyperv_timer.h?
>
I'm not sure whether the underscore matters in the vDSO data symbol, so
I follow the architectural name convention. If the leading underscore
doesn't have special purpose I'm happy to move this to arch neutral
header file.
> > +
> > static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
> > {
> > u64 res;
> > @@ -78,6 +92,11 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
> > if (clock_mode == VCLOCK_NONE)
> > return __VDSO_USE_SYSCALL;
> >
> > +#ifdef CONFIG_HYPERV_TIMER
> > + if (likely(clock_mode == VCLOCK_HVCLOCK))
> > + return vread_hvclock();
>
> I'm not sure likely() is justified here: it'll make ALL builds which
> enable CONFIG_HYPERV_TIMER (e.g. distro kernels) to prefer
> VCLOCK_HVCLOCK, even if the kernel is not running on Hyper-V.
>
Make sense. Thanks for pointing this out! I will change it in the next
version.
Regards,
Boqun
> > +#endif
> > +
> > /*
> > * This isb() is required to prevent that the counter value
> > * is speculated.
>
> --
> Vitaly
>
^ permalink raw reply
* [PATCH net] hv_netvsc: Fix unwanted rx_table reset
From: Haiyang Zhang @ 2019-12-20 2:28 UTC (permalink / raw)
To: sashal, linux-hyperv, netdev
Cc: haiyangz, kys, sthemmin, olaf, vkuznets, davem, linux-kernel
In existing code, the receive indirection table, rx_table, is in
struct rndis_device, which will be reset when changing MTU, ringparam,
etc. User configured receive indirection table values will be lost.
To fix this, move rx_table to struct net_device_context, and check
netif_is_rxfh_configured(), so rx_table will be set to default only
if no user configured value.
Fixes: ff4a44199012 ("netvsc: allow get/set of RSS indirection table")
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
drivers/net/hyperv/hyperv_net.h | 3 ++-
drivers/net/hyperv/netvsc_drv.c | 4 ++--
drivers/net/hyperv/rndis_filter.c | 10 +++++++---
3 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 9caa876..dc44819 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -169,7 +169,6 @@ struct rndis_device {
u8 hw_mac_adr[ETH_ALEN];
u8 rss_key[NETVSC_HASH_KEYLEN];
- u16 rx_table[ITAB_NUM];
};
@@ -940,6 +939,8 @@ struct net_device_context {
u32 tx_table[VRSS_SEND_TAB_SIZE];
+ u16 rx_table[ITAB_NUM];
+
/* Ethtool settings */
u8 duplex;
u32 speed;
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index eff8fef..68bf671 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -1662,7 +1662,7 @@ static int netvsc_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
rndis_dev = ndev->extension;
if (indir) {
for (i = 0; i < ITAB_NUM; i++)
- indir[i] = rndis_dev->rx_table[i];
+ indir[i] = ndc->rx_table[i];
}
if (key)
@@ -1692,7 +1692,7 @@ static int netvsc_set_rxfh(struct net_device *dev, const u32 *indir,
return -EINVAL;
for (i = 0; i < ITAB_NUM; i++)
- rndis_dev->rx_table[i] = indir[i];
+ ndc->rx_table[i] = indir[i];
}
if (!key) {
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 05bc5ec8..857c4be 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -773,6 +773,7 @@ static int rndis_set_rss_param_msg(struct rndis_device *rdev,
const u8 *rss_key, u16 flag)
{
struct net_device *ndev = rdev->ndev;
+ struct net_device_context *ndc = netdev_priv(ndev);
struct rndis_request *request;
struct rndis_set_request *set;
struct rndis_set_complete *set_complete;
@@ -812,7 +813,7 @@ static int rndis_set_rss_param_msg(struct rndis_device *rdev,
/* Set indirection table entries */
itab = (u32 *)(rssp + 1);
for (i = 0; i < ITAB_NUM; i++)
- itab[i] = rdev->rx_table[i];
+ itab[i] = ndc->rx_table[i];
/* Set hask key values */
keyp = (u8 *)((unsigned long)rssp + rssp->hashkey_offset);
@@ -1312,6 +1313,7 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
struct netvsc_device_info *device_info)
{
struct net_device *net = hv_get_drvdata(dev);
+ struct net_device_context *ndc = netdev_priv(net);
struct netvsc_device *net_device;
struct rndis_device *rndis_device;
struct ndis_recv_scale_cap rsscap;
@@ -1398,9 +1400,11 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
/* We will use the given number of channels if available. */
net_device->num_chn = min(net_device->max_chn, device_info->num_chn);
- for (i = 0; i < ITAB_NUM; i++)
- rndis_device->rx_table[i] = ethtool_rxfh_indir_default(
+ if (!netif_is_rxfh_configured(net)) {
+ for (i = 0; i < ITAB_NUM; i++)
+ ndc->rx_table[i] = ethtool_rxfh_indir_default(
i, net_device->num_chn);
+ }
atomic_set(&net_device->open_chn, 1);
vmbus_set_sc_create_callback(dev->channel, netvsc_sc_open);
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH net] hv_netvsc: Fix unwanted rx_table reset
From: David Miller @ 2019-12-21 5:50 UTC (permalink / raw)
To: haiyangz
Cc: sashal, linux-hyperv, netdev, kys, sthemmin, olaf, vkuznets,
linux-kernel
In-Reply-To: <1576808890-71212-1-git-send-email-haiyangz@microsoft.com>
From: Haiyang Zhang <haiyangz@microsoft.com>
Date: Thu, 19 Dec 2019 18:28:10 -0800
> In existing code, the receive indirection table, rx_table, is in
> struct rndis_device, which will be reset when changing MTU, ringparam,
> etc. User configured receive indirection table values will be lost.
>
> To fix this, move rx_table to struct net_device_context, and check
> netif_is_rxfh_configured(), so rx_table will be set to default only
> if no user configured value.
>
> Fixes: ff4a44199012 ("netvsc: allow get/set of RSS indirection table")
> Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Applied.
^ permalink raw reply
* RE: [Patch v2 1/2] PCI: hv: decouple the func definition in hv_dr_state from VSP message
From: Long Li @ 2019-12-22 2:47 UTC (permalink / raw)
To: Bjorn Helgaas, longli@linuxonhyperv.com
Cc: KY Srinivasan, Haiyang Zhang, Stephen Hemminger, Sasha Levin,
Lorenzo Pieralisi, Andrew Murray, linux-hyperv@vger.kernel.org,
linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <20191210235450.GA177105@google.com>
>Subject: Re: [Patch v2 1/2] PCI: hv: decouple the func definition in
>hv_dr_state from VSP message
>
>Run "git log --oneline drivers/pci/controller/pci-hyperv.c" and make yours
>match. Capitalize the first word, etc.
>
>On Tue, Dec 03, 2019 at 06:53:36PM -0800, longli@linuxonhyperv.com wrote:
>> From: Long Li <longli@microsoft.com>
>>
>> hv_dr_state is used to find present PCI devices on the bus. The
>> structure reuses struct pci_function_description from VSP message to
>describe a device.
>>
>> To prepare support for pci_function_description v2, we need to
>> decouple this dependence in hv_dr_state so it can work with both v1 and v2
>VSP messages.
>>
>> There is no functionality change.
>>
>> Signed-off-by: Long Li <longli@microsoft.com>
>
>> + * hv_pci_devices_present() - Handles list of new children
>> + * @hbus: Root PCI bus, as understood by this driver
>> + * @relations: Packet from host listing children
>> + *
>> + * This function is invoked whenever a new list of devices for
>> + * this bus appears.
>
>The comment should tell us what the function *does*, not when it is called.
I will send v3 to address the comments.
Thanks
Long
>
>> + */
>> +static void hv_pci_devices_present(struct hv_pcibus_device *hbus,
>> + struct pci_bus_relations *relations) {
>> + struct hv_dr_state *dr;
>> + int i;
>> +
>> + dr = kzalloc(offsetof(struct hv_dr_state, func) +
>> + (sizeof(struct hv_pcidev_description) *
>> + (relations->device_count)), GFP_NOWAIT);
>> +
>> + if (!dr)
>> + return;
>> +
>> + dr->device_count = relations->device_count;
>> + for (i = 0; i < dr->device_count; i++) {
>> + dr->func[i].v_id = relations->func[i].v_id;
>> + dr->func[i].d_id = relations->func[i].d_id;
>> + dr->func[i].rev = relations->func[i].rev;
>> + dr->func[i].prog_intf = relations->func[i].prog_intf;
>> + dr->func[i].subclass = relations->func[i].subclass;
>> + dr->func[i].base_class = relations->func[i].base_class;
>> + dr->func[i].subsystem_id = relations->func[i].subsystem_id;
>> + dr->func[i].win_slot = relations->func[i].win_slot;
>> + dr->func[i].ser = relations->func[i].ser;
>> + }
>> +
>> + if (hv_pci_start_relations_work(hbus, dr))
>> + kfree(dr);
>> }
^ permalink raw reply
* [PATCH] x86/hyper-v: add "polling" bit to hv_synic_sint
From: Wei Liu @ 2019-12-22 23:34 UTC (permalink / raw)
To: linux-hyperv
Cc: sashal, kys, haiyangz, sthemmin, x86, mikelley, linux-kernel,
Wei Liu
That bit is documented in TLFS 5.0c as follows:
Setting the polling bit will have the effect of unmasking an
interrupt source, except that an actual interrupt is not generated.
Signed-off-by: Wei Liu <wei.liu@kernel.org>
---
arch/x86/include/asm/hyperv-tlfs.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
index 5f10f7f2098d..92abc1e42bfc 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -809,7 +809,8 @@ union hv_synic_sint {
u64 reserved1:8;
u64 masked:1;
u64 auto_eoi:1;
- u64 reserved2:46;
+ u64 polling:1;
+ u64 reserved2:45;
} __packed;
};
--
2.20.1
^ permalink raw reply related
* RE: [PATCH] x86/hyper-v: add "polling" bit to hv_synic_sint
From: Michael Kelley @ 2019-12-23 14:41 UTC (permalink / raw)
To: Wei Liu, linux-hyperv@vger.kernel.org
Cc: sashal@kernel.org, KY Srinivasan, Haiyang Zhang,
Stephen Hemminger, x86@kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <20191222233404.1629-1-wei.liu@kernel.org>
From: Wei Liu <wei.liu@kernel.org> Sent: Sunday, December 22, 2019 3:34 PM
> To: linux-hyperv@vger.kernel.org
> Cc: sashal@kernel.org; KY Srinivasan <kys@microsoft.com>; Haiyang Zhang
> <haiyangz@microsoft.com>; Stephen Hemminger <sthemmin@microsoft.com>;
> x86@kernel.org; Michael Kelley <mikelley@microsoft.com>; linux-kernel@vger.kernel.org;
> Wei Liu <wei.liu@kernel.org>
> Subject: [PATCH] x86/hyper-v: add "polling" bit to hv_synic_sint
>
> That bit is documented in TLFS 5.0c as follows:
>
> Setting the polling bit will have the effect of unmasking an
> interrupt source, except that an actual interrupt is not generated.
>
> Signed-off-by: Wei Liu <wei.liu@kernel.org>
> ---
> arch/x86/include/asm/hyperv-tlfs.h | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
> index 5f10f7f2098d..92abc1e42bfc 100644
> --- a/arch/x86/include/asm/hyperv-tlfs.h
> +++ b/arch/x86/include/asm/hyperv-tlfs.h
> @@ -809,7 +809,8 @@ union hv_synic_sint {
> u64 reserved1:8;
> u64 masked:1;
> u64 auto_eoi:1;
> - u64 reserved2:46;
> + u64 polling:1;
> + u64 reserved2:45;
> } __packed;
> };
>
> --
> 2.20.1
Reviewed-by: Michael Kelley <mikelley@microsoft.com>
^ permalink raw reply
* flow control in vmbus ring buffers
From: Roman Kagan @ 2019-12-24 10:56 UTC (permalink / raw)
To: linux-hyperv@vger.kernel.org
I'm trying to get my head around how the flow control in vmbus ring
buffers works.
In particular, I'm failing to see how the following can be prevented:
producer | consumer
==================================================================
read read_index |
(enough room for packet) |
write pending_send_sz = 0 |
write packet |
update write_index |
| read write_index
read read_index | read packet
(not enough room for packet) | update read_index (= write_index)
| read pending_send_sz = 0
write pending_send_sz = X | skip notification
go to sleep | go to sleep
stall
Could anybody please shed some light on how it's supposed to work?
Thanks,
Roman.
^ permalink raw reply
* Re: flow control in vmbus ring buffers
From: Roman Kagan @ 2019-12-24 16:28 UTC (permalink / raw)
To: linux-hyperv@vger.kernel.org
In-Reply-To: <20191224105605.GA164618@rkaganb.sw.ru>
On Tue, Dec 24, 2019 at 10:56:08AM +0000, Roman Kagan wrote:
> I'm trying to get my head around how the flow control in vmbus ring
> buffers works.
>
> In particular, I'm failing to see how the following can be prevented:
>
>
> producer | consumer
> ==================================================================
> read read_index |
> (enough room for packet) |
> write pending_send_sz = 0 |
> write packet |
> update write_index |
> | read write_index
> read read_index | read packet
> (not enough room for packet) | update read_index (= write_index)
> | read pending_send_sz = 0
> write pending_send_sz = X | skip notification
> go to sleep | go to sleep
> stall
>
> Could anybody please shed some light on how it's supposed to work?
Sorry to reply to myself, but looks like the answer is to re-read
read_index on the producer side after setting pending_send_sz.
Thanks and sorry for the noise,
Roman.
^ permalink raw reply
* RE: flow control in vmbus ring buffers
From: Michael Kelley @ 2019-12-24 18:03 UTC (permalink / raw)
To: Roman Kagan, linux-hyperv@vger.kernel.org
In-Reply-To: <20191224162832.GA168681@rkaganb.sw.ru>
From: Roman Kagan <rkagan@virtuozzo.com> Sent: Tuesday, December 24, 2019 8:29 AM
>
> On Tue, Dec 24, 2019 at 10:56:08AM +0000, Roman Kagan wrote:
> > I'm trying to get my head around how the flow control in vmbus ring
> > buffers works.
> >
> > In particular, I'm failing to see how the following can be prevented:
> >
> >
> > producer | consumer
> > ==================================================================
> > read read_index |
> > (enough room for packet) |
> > write pending_send_sz = 0 |
> > write packet |
> > update write_index |
> > | read write_index
> > read read_index | read packet
> > (not enough room for packet) | update read_index (= write_index)
> > | read pending_send_sz = 0
> > write pending_send_sz = X | skip notification
> > go to sleep | go to sleep
> > stall
> >
> > Could anybody please shed some light on how it's supposed to work?
>
> Sorry to reply to myself, but looks like the answer is to re-read
> read_index on the producer side after setting pending_send_sz.
>
Are you seeing a problem in the Linux guest code in drivers/hv/ring_buffer.c?
The only time the Linux guest as the producer sets pending_send_sz is in the
hv_socket code. Or are you looking at the KVM code that does emulation of
Hyper-V, where KVM is acting as the producer?
Just curious as to what prompted your question. I did the most recent fixes a
couple years ago to the Linux guest code for handling the ring buffer interaction
with Hyper-V, and if there is still a problem, I'm super interested. :-)
Michael
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox