* Re: [RFT PATCH] x86/hyperv: Use __naked attribute to fix stackless C function
From: Wei Liu @ 2026-02-27 21:50 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: linux-kernel, Ard Biesheuvel, Mukesh Rathor, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, H. Peter Anvin,
Uros Bizjak, linux-hyperv
In-Reply-To: <20260226095056.46410-2-ardb+git@google.com>
On Thu, Feb 26, 2026 at 10:50:57AM +0100, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb@kernel.org>
>
> hv_crash_c_entry() is a C function that is entered without a stack,
> and this is only allowed for functions that have the __naked attribute,
> which informs the compiler that it must not emit the usual prologue and
> epilogue or emit any other kind of instrumentation that relies on a
> stack frame.
>
> So split up the function, and set the __naked attribute on the initial
> part that sets up the stack, GDT, IDT and other pieces that are needed
> for ordinary C execution. Given that function calls are not permitted
> either, use the existing long return coded in an asm() block to call the
> second part of the function, which is an ordinary function that is
> permitted to call other functions as usual.
>
> Fixes: 94212d34618c ("x86/hyperv: Implement hypervisor RAM collection into vmcore")
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Ard, thank you for the patch.
For avoidance of doubt, I expect another version to be sent. We will
review and test the new version on our side.
Wei
^ permalink raw reply
* Re: [PATCH v1 5/6] x86/hyperv: Implement hypervisor ram collection into vmcore
From: Wei Liu @ 2026-02-27 21:37 UTC (permalink / raw)
To: Mukesh R, ardb
Cc: Ard Biesheuvel, linux-hyperv, linux-kernel, linux-arch, kys,
haiyangz, wei.liu, decui, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, dave.hansen, x86, H . Peter Anvin, Arnd Bergmann
In-Reply-To: <6a601546-a26f-79f6-a3b0-be145dfa7781@linux.microsoft.com>
On Fri, Feb 27, 2026 at 12:05:13PM -0800, Mukesh R wrote:
[...]
> >
> > So? But does it means to 'be in asmlinkage' in your interpretation? Did you check what 'asmlinkage' actually evaluates to?
> >
> > I am not asking you to justify why this broken code works in practice, I am asking you to fix it.
>
>
> STOP bossing me! I am not your servant nor your slave. And you are not the
> only genius around here.
>
> Now, many people looked at this code before it was merged and no one really
> thought any self respecting compiler in modern times would create an issue
> here. Still, I see the remote possibility of that happening. All you had
> to do was to show your concern and suggest using __naked here (which looks
> like we all missed, or maybe it came after the code was written), and it
> would have been addressed. This is x64 specific code for very special case
> of hyperv or kernel-on-hyperv crashing.
>
> In future if you choose to correspond, watch your tone!
Mukesh, there is no need to be so emotional and defensive.
I don't think anyone, no matter how good he or she is, knows all the
intricacies in the kernel. We're lucky to have other people look at our
code and point out potential issues. Regardless of your opinion on the
discussion, we should be thankful for the time and effort people put
into even sending an email, let alone a patch.
Let's keep the discussion civil and constructive, and focus on the
technical aspects of the code.
Ard, I want to let you know that I appreciate you raising this issue
with us.
Thanks,
Wei
^ permalink raw reply
* Re: [PATCH v1 4/4] page_reporting: change PAGE_REPORTING_DEFAULT_ORDER to -1
From: David Hildenbrand (Arm) @ 2026-02-27 20:50 UTC (permalink / raw)
To: Yuvraj Sakshith, akpm
Cc: mst, kys, haiyangz, wei.liu, decui, longli, jasowang, xuanzhuo,
eperezma, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb,
mhocko, jackmanb, hannes, ziy, linux-hyperv, virtualization,
linux-mm, linux-kernel
In-Reply-To: <20260227140655.360696-5-yuvraj.sakshith@oss.qualcomm.com>
On 2/27/26 15:06, Yuvraj Sakshith wrote:
> PAGE_REPORTING_DEFAULT_ORDER is now set to zero. This means,
> pages of order zero cannot be reported to a client/driver -- as zero
> is used to signal a fallback to MAX_PAGE_ORDER.
>
> Change PAGE_REPORTING_DEFAULT_ORDER to (-1),
> so that zero can be used as a valid order with which pages can
> be reported.
>
> Signed-off-by: Yuvraj Sakshith <yuvraj.sakshith@oss.qualcomm.com>
> ---
> include/linux/page_reporting.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/linux/page_reporting.h b/include/linux/page_reporting.h
> index a7e3e30f2..3eb3e26d8 100644
> --- a/include/linux/page_reporting.h
> +++ b/include/linux/page_reporting.h
> @@ -7,7 +7,7 @@
>
> /* This value should always be a power of 2, see page_reporting_cycle() */
> #define PAGE_REPORTING_CAPACITY 32
> -#define PAGE_REPORTING_DEFAULT_ORDER 0
> +#define PAGE_REPORTING_DEFAULT_ORDER (-1)
No need for the ().
Wondering whether we now also want to do in this patch:
diff --git a/mm/page_reporting.c b/mm/page_reporting.c
index f0042d5743af..d432aadf9d07 100644
--- a/mm/page_reporting.c
+++ b/mm/page_reporting.c
@@ -11,8 +11,7 @@
#include "page_reporting.h"
#include "internal.h"
-/* Initialize to an unsupported value */
-unsigned int page_reporting_order = -1;
+unsigned int page_reporting_order = PAGE_REPORTING_DEFAULT_ORDER;
static int page_order_update_notify(const char *val, const struct
kernel_param *kp)
{
@@ -369,7 +368,7 @@ int page_reporting_register(struct
page_reporting_dev_info *prdev)
* pageblock_order.
*/
- if (page_reporting_order == -1) {
+ if (page_reporting_order == PAGE_REPORTING_DEFAULT_ORDER) {
(and wondering whether we should have called it
PAGE_REPORTING_USE_DEFAULT_ORDER to make it clearer that it is not an
actual order. Leaving that up to you :) )
--
Cheers,
David
^ permalink raw reply related
* Re: [PATCH v1 2/4] virtio_balloon: set default page reporting order
From: David Hildenbrand (Arm) @ 2026-02-27 20:46 UTC (permalink / raw)
To: Yuvraj Sakshith, akpm
Cc: mst, kys, haiyangz, wei.liu, decui, longli, jasowang, xuanzhuo,
eperezma, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb,
mhocko, jackmanb, hannes, ziy, linux-hyperv, virtualization,
linux-mm, linux-kernel
In-Reply-To: <20260227140655.360696-3-yuvraj.sakshith@oss.qualcomm.com>
On 2/27/26 15:06, Yuvraj Sakshith wrote:
> virtio_balloon page reporting order is set to MAX_PAGE_ORDER implicitly
> as vb->prdev.order is never initialised and is auto-set to zero.
>
> Explicitly mention usage of default page order by making use of
> PAGE_REPORTING_DEFAULT ORDER fallback value.
>
> Signed-off-by: Yuvraj Sakshith <yuvraj.sakshith@oss.qualcomm.com>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
--
Cheers,
David
^ permalink raw reply
* Re: [PATCH v1 1/4] page_reporting: add PAGE_REPORTING_DEFAULT_ORDER
From: David Hildenbrand (Arm) @ 2026-02-27 20:45 UTC (permalink / raw)
To: Yuvraj Sakshith, akpm
Cc: mst, kys, haiyangz, wei.liu, decui, longli, jasowang, xuanzhuo,
eperezma, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb,
mhocko, jackmanb, hannes, ziy, linux-hyperv, virtualization,
linux-mm, linux-kernel
In-Reply-To: <20260227140655.360696-2-yuvraj.sakshith@oss.qualcomm.com>
On 2/27/26 15:06, Yuvraj Sakshith wrote:
> Drivers can pass order of pages to be reported while
> registering itself. Today, this is a magic number, 0.
>
> Label this with PAGE_REPORTING_DEFAULT_ORDER and
> check for it when the driver is being registered.
Patch subject: "mm/page_reporting:"
Might want to add "We'll make explicit use of this define in relevant
drivers next."
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
--
Cheers,
David
^ permalink raw reply
* Re: [PATCH v1 0/4] Allow order zero pages in page reporting
From: David Hildenbrand (Arm) @ 2026-02-27 20:44 UTC (permalink / raw)
To: Yuvraj Sakshith, akpm
Cc: mst, kys, haiyangz, wei.liu, decui, longli, jasowang, xuanzhuo,
eperezma, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb,
mhocko, jackmanb, hannes, ziy, linux-hyperv, virtualization,
linux-mm, linux-kernel
In-Reply-To: <20260227140655.360696-1-yuvraj.sakshith@oss.qualcomm.com>
On 2/27/26 15:06, Yuvraj Sakshith wrote:
> Today, page reporting sets page_reporting_order in two ways:
>
> (1) page_reporting.page_reporting_order cmdline parameter
> (2) Driver can pass order while registering itself.
>
> In both cases, order zero is ignored by free page reporting
> because it is used to set page_reporting_order to a default
> value, like MAX_PAGE_ORDER.
>
> In some cases we might want page_reporting_order to be zero.
>
> For instance, when virtio-balloon runs inside a guest with
> tiny memory (say, 16MB), it might not be able to find a order 1 page
> (or in the worst case order MAX_PAGE_ORDER page) after some uptime.
> Page reporting should be able to return order zero pages back for
> optimal memory relinquishment.
>
> This patch changes the default fallback value from '0' to '-1' in
> all possible clients of free page reporting (hv_balloon and
> virtio-balloon) together with allowing '0' as a valid order in
> page_reporting_register().
>
> Changes in v1:
> - Introduce PAGE_REPORTING_DEFAULT_ORDER macro (initially set to 0).
> - Make use of new macro in drivers (hv_balloon and virtio-balloon)
> working with page reporting.
> - Change PAGE_REPORTING_DEFAULT_ORDER to -1 as zero is a valid
> page order that can be requested.
>
> Yuvraj Sakshith (3):
> mm/page_reporting: Allow zero page_reporting_order
> hv_balloon: Change default page reporting order
> virtio_balloon: Set pr_dev.order to new default
These look like old stats :)
--
Cheers,
David
^ permalink raw reply
* Re: VFIO support on hyperv (vfio_pci_core_ioctl())
From: Mukesh R @ 2026-02-27 20:06 UTC (permalink / raw)
To: Alex Williamson; +Cc: kvm, wei.liu@kernel.org, linux-hyperv@vger.kernel.org
In-Reply-To: <20260227122957.1e555024@shazbot.org>
On 2/27/26 11:29, Alex Williamson wrote:
> On Wed, 25 Feb 2026 14:04:49 -0800
> Mukesh R <mrathor@linux.microsoft.com> wrote:
>
>> Hi Alex et al:
>>
>> I've been looking at making pci passthru irq setup/remap work on hyperv
>> for the latest (6.19) version using vfio core. Unfortunately, it's just
>> not fitting well because in case of hyperv the irq remap is done by
>> the hypervisor. Specifically, for a robust and proper solution, we need
>> to override vfio_pci_set_msi_trigger(). As such, for the best way forward
>> I am trying to figure how much flexibility there is to modify
>> vfio_pci_intrs.c with "if (running_on_hyperv())" branches (putting hyperv
>> code in separate file).
>>
>> If none, then the alternative would be to create vfio-hyperv.c with
>> vfio_device_ops.ioctl = hyperv_vfio_pci_core_ioctl(). But, then I'd
>> be replicating code for other sub ioctls like vfio_pci_ioctl_get_info(),
>> vfio_pci_ioctl_get_irq_info(), etc. Would it be acceptable to make them
>> non static in this case?
>>
>> Please let me know your thoughts or if you have other suggestions.
>
> Hi Mukesh,
>
> In general, littering the code with running_on_hyperv() tests is not
> acceptable, but the presented alternative isn't really accurate either.
> If you want to substitute in your own ioctl callback, you can still
> call vfio_pci_core_ioctl() for all the unhandled ioctls, without extra
Yes, I realized that after looking at how other callers were using it.
> exports. We can also look at whether vfio_pci_device_ops could have a
> callback specifically addressing an alternative set_msi_trigger
> handler. Thanks,
Sounds good. thanks as always,
-Mukesh
> Alex
^ permalink raw reply
* Re: [PATCH v1 5/6] x86/hyperv: Implement hypervisor ram collection into vmcore
From: Mukesh R @ 2026-02-27 20:05 UTC (permalink / raw)
To: Ard Biesheuvel, linux-hyperv, linux-kernel, linux-arch
Cc: kys, haiyangz, wei.liu, decui, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, dave.hansen, x86, H . Peter Anvin, Arnd Bergmann
In-Reply-To: <eb1c44d7-2664-4269-8824-e90e5a8494b2@app.fastmail.com>
On 2/25/26 23:44, Ard Biesheuvel wrote:
>
> On Wed, 25 Feb 2026, at 23:27, Mukesh R wrote:
>> On 2/21/26 08:43, Ard Biesheuvel wrote:
>>> Just spotted this code in v7.0-rc
>>>
>>> On Wed, 10 Sep 2025, at 02:10, Mukesh Rathor wrote:
>>> ...
>>>
>>>> +static asmlinkage void __noreturn hv_crash_c_entry(void)
>>>
>>> 'asmlinkage' means that the function may be called from another compilation unit written in assembler, but it doesn't actually evaluate to anything in most cases. Combining it with 'static' makes no sense whatsoever.
>>
>> 'static' means scope is limited to the file. Common in cases where function
>> pointers are used, like here in this file way below.
>>
>> Like the comment says:
>> "This is the C entry point from the asm glue code after...."
>>
>> IOW, called from assembly function (asm == assembly).
>>
>
> I wasn't asking you to explain what 'static' means. I was explaining to you that asmlinkage means 'external linkage' whereas 'static' means the opposite, and so combining them makes no sense.
>
>
>>>
>>>> +{
>>>> + struct hv_crash_ctxt *ctxt = &hv_crash_ctxt;
>>>> +
>>>> + /* first thing, restore kernel gdt */
>>>> + native_load_gdt(&ctxt->gdtr);
>>>> +
>>>> + asm volatile("movw %%ax, %%ss" : : "a"(ctxt->ss));
>>>> + asm volatile("movq %0, %%rsp" : : "m"(ctxt->rsp));
>>>> +
>>>
>>> This code is truly very broken. You cannot enter a C function without a stack, and assign RSP half way down the function. Especially after allocating local variables and/or calling other functions - it may happen to work in most cases, but it is very fragile. (Other architectures have the concept of 'naked' functions for this purpose but x86 does not)
>>
>> Local variable refers to static bss struct. IOW,
>>
>> asm volatile("movq %0, %%rsp" : : "m"(ctxt->rsp));
>>
>> same as:
>> asm volatile("movq %0, %%rsp" : : "m"(&hv_crash_ctxt.rsp));
>>
>>
>
> No, it is *not* the same. In practice, the compiler might perform this substitution, but there is no guarantee that this happens.
>
>
>>> IOW, this whole function should be written in asm.
>>>> + asm volatile("movw %%ax, %%ds" : : "a"(ctxt->ds));
>>>> + asm volatile("movw %%ax, %%es" : : "a"(ctxt->es));
>>>> + asm volatile("movw %%ax, %%fs" : : "a"(ctxt->fs));
>>>> + asm volatile("movw %%ax, %%gs" : : "a"(ctxt->gs));
>>>> +
>>>> + native_wrmsrq(MSR_IA32_CR_PAT, ctxt->pat);
>>>> + asm volatile("movq %0, %%cr0" : : "r"(ctxt->cr0));
>>>> +
>>>> + asm volatile("movq %0, %%cr8" : : "r"(ctxt->cr8));
>>>> + asm volatile("movq %0, %%cr4" : : "r"(ctxt->cr4));
>>>> + asm volatile("movq %0, %%cr2" : : "r"(ctxt->cr4));
>>>> +
>>>> + native_load_idt(&ctxt->idtr);
>>>> + native_wrmsrq(MSR_GS_BASE, ctxt->gsbase);
>>>> + native_wrmsrq(MSR_EFER, ctxt->efer);
>>>> +
>>>> + /* restore the original kernel CS now via far return */
>>>> + asm volatile("movzwq %0, %%rax\n\t"
>>>> + "pushq %%rax\n\t"
>>>> + "pushq $1f\n\t"
>>>> + "lretq\n\t"
>>>> + "1:nop\n\t" : : "m"(ctxt->cs) : "rax");
>>>> +
>>>> + /* We are in asmlinkage without stack frame,
>>>
>>> You just switched to __KERNEL_CS via the stack.
>>
>> compiler doesn't know that.
>>
>
> So? But does it means to 'be in asmlinkage' in your interpretation? Did you check what 'asmlinkage' actually evaluates to?
>
> I am not asking you to justify why this broken code works in practice, I am asking you to fix it.
STOP bossing me! I am not your servant nor your slave. And you are not the
only genius around here.
Now, many people looked at this code before it was merged and no one really
thought any self respecting compiler in modern times would create an issue
here. Still, I see the remote possibility of that happening. All you had
to do was to show your concern and suggest using __naked here (which looks
like we all missed, or maybe it came after the code was written), and it
would have been addressed. This is x64 specific code for very special case
of hyperv or kernel-on-hyperv crashing.
In future if you choose to correspond, watch your tone!
>>>> hence make a C function
>>>> + * call which will buy stack frame to restore the tss or clear PT
>>>> entry.
>>>> + */
>>>
>>> Where does one buy a stack frame?
>>
>> A stack market :). Callee will create stack frame now that rsp is
>> setup.
>>
>
> This code is beyond broken. Please propose fixes rather than try to argue why carrying broken code like this is acceptable.
^ permalink raw reply
* Re: VFIO support on hyperv (vfio_pci_core_ioctl())
From: Alex Williamson @ 2026-02-27 19:29 UTC (permalink / raw)
To: Mukesh R; +Cc: kvm, wei.liu@kernel.org, linux-hyperv@vger.kernel.org, alex
In-Reply-To: <1f50dae2-ec4a-7914-a14f-2ada803eb0e3@linux.microsoft.com>
On Wed, 25 Feb 2026 14:04:49 -0800
Mukesh R <mrathor@linux.microsoft.com> wrote:
> Hi Alex et al:
>
> I've been looking at making pci passthru irq setup/remap work on hyperv
> for the latest (6.19) version using vfio core. Unfortunately, it's just
> not fitting well because in case of hyperv the irq remap is done by
> the hypervisor. Specifically, for a robust and proper solution, we need
> to override vfio_pci_set_msi_trigger(). As such, for the best way forward
> I am trying to figure how much flexibility there is to modify
> vfio_pci_intrs.c with "if (running_on_hyperv())" branches (putting hyperv
> code in separate file).
>
> If none, then the alternative would be to create vfio-hyperv.c with
> vfio_device_ops.ioctl = hyperv_vfio_pci_core_ioctl(). But, then I'd
> be replicating code for other sub ioctls like vfio_pci_ioctl_get_info(),
> vfio_pci_ioctl_get_irq_info(), etc. Would it be acceptable to make them
> non static in this case?
>
> Please let me know your thoughts or if you have other suggestions.
Hi Mukesh,
In general, littering the code with running_on_hyperv() tests is not
acceptable, but the presented alternative isn't really accurate either.
If you want to substitute in your own ioctl callback, you can still
call vfio_pci_core_ioctl() for all the unhandled ioctls, without extra
exports. We can also look at whether vfio_pci_device_ops could have a
callback specifically addressing an alternative set_msi_trigger
handler. Thanks,
Alex
^ permalink raw reply
* RE: [PATCH net-next, v2] net: mana: Trigger VF reset/recovery on health check failure due to HWC timeout
From: Haiyang Zhang @ 2026-02-27 19:24 UTC (permalink / raw)
To: Dipayaan Roy, KY Srinivasan, wei.liu@kernel.org, Dexuan Cui,
andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com, leon@kernel.org, Long Li,
Konstantin Taranov, horms@kernel.org,
shradhagupta@linux.microsoft.com, ssengar@linux.microsoft.com,
ernis@linux.microsoft.com, Shiraz Saleem,
linux-hyperv@vger.kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-rdma@vger.kernel.org,
Dipayaan Roy
In-Reply-To: <aaFShvKnwR5FY8dH@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net>
> -----Original Message-----
> From: Dipayaan Roy <dipayanroy@linux.microsoft.com>
> Sent: Friday, February 27, 2026 3:15 AM
> To: KY Srinivasan <kys@microsoft.com>; Haiyang Zhang
> <haiyangz@microsoft.com>; wei.liu@kernel.org; Dexuan Cui
> <DECUI@microsoft.com>; andrew+netdev@lunn.ch; davem@davemloft.net;
> edumazet@google.com; kuba@kernel.org; pabeni@redhat.com; leon@kernel.org;
> Long Li <longli@microsoft.com>; Konstantin Taranov
> <kotaranov@microsoft.com>; horms@kernel.org;
> shradhagupta@linux.microsoft.com; ssengar@linux.microsoft.com;
> ernis@linux.microsoft.com; Shiraz Saleem <shirazsaleem@microsoft.com>;
> linux-hyperv@vger.kernel.org; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org; linux-rdma@vger.kernel.org; Dipayaan Roy
> <dipayanroy@microsoft.com>
> Subject: [PATCH net-next, v2] net: mana: Trigger VF reset/recovery on
> health check failure due to HWC timeout
>
> The GF stats periodic query is used as mechanism to monitor HWC health
> check. If this HWC command times out, it is a strong indication that
> the device/SoC is in a faulty state and requires recovery.
>
> Today, when a timeout is detected, the driver marks
> hwc_timeout_occurred, clears cached stats, and stops rescheduling the
> periodic work. However, the device itself is left in the same failing
> state.
>
> Extend the timeout handling path to trigger the existing MANA VF
> recovery service by queueing a GDMA_EQE_HWC_RESET_REQUEST work item.
> This is expected to initiate the appropriate recovery flow by suspende
> resume first and if it fails then trigger a bus rescan.
>
> This change is intentionally limited to HWC command timeouts and does
> not trigger recovery for errors reported by the SoC as a normal command
> response.
>
> Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
> ---
> Changes in v2:
> - Added common helper, proper clearing of gc flags.
> ---
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
Thanks.
^ permalink raw reply
* Re: [PATCH net-next v4] net: mana: Add MAC address to vPort logs and clarify error messages
From: Erni Sri Satya Vennela @ 2026-02-27 19:06 UTC (permalink / raw)
To: kys, haiyangz, wei.liu, decui, longli, andrew+netdev, davem,
edumazet, kuba, pabeni, dipayanroy, shirazsaleem, ssengar,
shradhagupta, gargaditya, linux-hyperv, netdev, linux-kernel
In-Reply-To: <20260225192252.943534-1-ernis@linux.microsoft.com>
On Wed, Feb 25, 2026 at 11:22:41AM -0800, Erni Sri Satya Vennela wrote:
> Add MAC address to vPort configuration success message and update error
> message to be more specific about HWC message errors in
> mana_send_request.
>
> Signed-off-by: Erni Sri Satya Vennela <ernis@linux.microsoft.com>
Gentle ping — I sent this patch on 25/02/2026 and would appreciate any
feedback when you have time.
Happy to rebase or add more details if needed, thanks for your review.
Regards,
Vennela
^ permalink raw reply
* Re: [PATCH net-next] net: mana: Expose page_pool stats via ethtool
From: Jakub Kicinski @ 2026-02-27 17:27 UTC (permalink / raw)
To: Dipayaan Roy
Cc: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
pabeni, leon, longli, kotaranov, horms, shradhagupta, ssengar,
ernis, shirazsaleem, linux-hyperv, netdev, linux-kernel,
linux-rdma, dipayanroy
In-Reply-To: <aaFmRqjjOuPIEo5x@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net>
On Fri, 27 Feb 2026 01:39:18 -0800 Dipayaan Roy wrote:
> MANA relies on page_pool for RX buffers, and the buffer refill paths
> can behave quite differently across architectures and configurations (e.g.
> base page size, fragment vs full-page usage). This makes it harder to
> understand and compare RX buffer behavior when investigating performance
> and memory differences across platforms.
Standard stats must not be duplicated in ethtool -S.
ynl and ynltool provide easy access to these stats
# ynltool page-pool stats
eth0[2] page pools: 44 (zombies: 0)
refs: 495680 bytes: 2030305280 (refs: 0 bytes: 0)
recycling: 100.0% (alloc: 7745:2097593009 recycle: 379301630:1717888312)
^ permalink raw reply
* Re: [PATCH] scsi: storvsc: Fix scheduling while atomic on PREEMPT_RT
From: Jan Kiszka @ 2026-02-27 15:55 UTC (permalink / raw)
To: Martin K. Petersen, K. Y. Srinivasan, Haiyang Zhang, Wei Liu,
Dexuan Cui, Long Li, James E.J. Bottomley, linux-hyperv
Cc: linux-scsi, Linux Kernel Mailing List, Florian Bezdeka, RT,
Mitchell Levy
In-Reply-To: <177195161164.1154639.10246495163151300179.b4-ty@oracle.com>
On 24.02.26 17:47, Martin K. Petersen wrote:
> On Thu, 29 Jan 2026 15:30:39 +0100, Jan Kiszka wrote:
>
>> This resolves the follow splat and lock-up when running with PREEMPT_RT
>> enabled on Hyper-V:
>>
>> [ 415.140818] BUG: scheduling while atomic: stress-ng-iomix/1048/0x00000002
>> [ 415.140822] INFO: lockdep is turned off.
>> [ 415.140823] Modules linked in: intel_rapl_msr intel_rapl_common intel_uncore_frequency_common intel_pmc_core pmt_telemetry pmt_discovery pmt_class intel_pmc_ssram_telemetry intel_vsec ghash_clmulni_intel aesni_intel rapl binfmt_misc nls_ascii nls_cp437 vfat fat snd_pcm hyperv_drm snd_timer drm_client_lib drm_shmem_helper snd sg soundcore drm_kms_helper pcspkr hv_balloon hv_utils evdev joydev drm configfs efi_pstore nfnetlink vsock_loopback vmw_vsock_virtio_transport_common hv_sock vmw_vsock_vmci_transport vsock vmw_vmci efivarfs autofs4 ext4 crc16 mbcache jbd2 sr_mod sd_mod cdrom hv_storvsc serio_raw hid_generic scsi_transport_fc hid_hyperv scsi_mod hid hv_netvsc hyperv_keyboard scsi_common
>> [ 415.140846] Preemption disabled at:
>> [ 415.140847] [<ffffffffc0656171>] storvsc_queuecommand+0x2e1/0xbe0 [hv_storvsc]
>> [ 415.140854] CPU: 8 UID: 0 PID: 1048 Comm: stress-ng-iomix Not tainted 6.19.0-rc7 #30 PREEMPT_{RT,(full)}
>> [ 415.140856] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v4.1 09/04/2024
>> [ 415.140857] Call Trace:
>> [ 415.140861] <TASK>
>> [ 415.140861] ? storvsc_queuecommand+0x2e1/0xbe0 [hv_storvsc]
>> [ 415.140863] dump_stack_lvl+0x91/0xb0
>> [ 415.140870] __schedule_bug+0x9c/0xc0
>> [ 415.140875] __schedule+0xdf6/0x1300
>> [ 415.140877] ? rtlock_slowlock_locked+0x56c/0x1980
>> [ 415.140879] ? rcu_is_watching+0x12/0x60
>> [ 415.140883] schedule_rtlock+0x21/0x40
>> [ 415.140885] rtlock_slowlock_locked+0x502/0x1980
>> [ 415.140891] rt_spin_lock+0x89/0x1e0
>> [ 415.140893] hv_ringbuffer_write+0x87/0x2a0
>> [ 415.140899] vmbus_sendpacket_mpb_desc+0xb6/0xe0
>> [ 415.140900] ? rcu_is_watching+0x12/0x60
>> [ 415.140902] storvsc_queuecommand+0x669/0xbe0 [hv_storvsc]
>> [ 415.140904] ? HARDIRQ_verbose+0x10/0x10
>> [ 415.140908] ? __rq_qos_issue+0x28/0x40
>> [ 415.140911] scsi_queue_rq+0x760/0xd80 [scsi_mod]
>> [ 415.140926] __blk_mq_issue_directly+0x4a/0xc0
>> [ 415.140928] blk_mq_issue_direct+0x87/0x2b0
>> [ 415.140931] blk_mq_dispatch_queue_requests+0x120/0x440
>> [ 415.140933] blk_mq_flush_plug_list+0x7a/0x1a0
>> [ 415.140935] __blk_flush_plug+0xf4/0x150
>> [ 415.140940] __submit_bio+0x2b2/0x5c0
>> [ 415.140944] ? submit_bio_noacct_nocheck+0x272/0x360
>> [ 415.140946] submit_bio_noacct_nocheck+0x272/0x360
>> [ 415.140951] ext4_read_bh_lock+0x3e/0x60 [ext4]
>> [ 415.140995] ext4_block_write_begin+0x396/0x650 [ext4]
>> [ 415.141018] ? __pfx_ext4_da_get_block_prep+0x10/0x10 [ext4]
>> [ 415.141038] ext4_da_write_begin+0x1c4/0x350 [ext4]
>> [ 415.141060] generic_perform_write+0x14e/0x2c0
>> [ 415.141065] ext4_buffered_write_iter+0x6b/0x120 [ext4]
>> [ 415.141083] vfs_write+0x2ca/0x570
>> [ 415.141087] ksys_write+0x76/0xf0
>> [ 415.141089] do_syscall_64+0x99/0x1490
>> [ 415.141093] ? rcu_is_watching+0x12/0x60
>> [ 415.141095] ? finish_task_switch.isra.0+0xdf/0x3d0
>> [ 415.141097] ? rcu_is_watching+0x12/0x60
>> [ 415.141098] ? lock_release+0x1f0/0x2a0
>> [ 415.141100] ? rcu_is_watching+0x12/0x60
>> [ 415.141101] ? finish_task_switch.isra.0+0xe4/0x3d0
>> [ 415.141103] ? rcu_is_watching+0x12/0x60
>> [ 415.141104] ? __schedule+0xb34/0x1300
>> [ 415.141106] ? hrtimer_try_to_cancel+0x1d/0x170
>> [ 415.141109] ? do_nanosleep+0x8b/0x160
>> [ 415.141111] ? hrtimer_nanosleep+0x89/0x100
>> [ 415.141114] ? __pfx_hrtimer_wakeup+0x10/0x10
>> [ 415.141116] ? xfd_validate_state+0x26/0x90
>> [ 415.141118] ? rcu_is_watching+0x12/0x60
>> [ 415.141120] ? do_syscall_64+0x1e0/0x1490
>> [ 415.141121] ? do_syscall_64+0x1e0/0x1490
>> [ 415.141123] ? rcu_is_watching+0x12/0x60
>> [ 415.141124] ? do_syscall_64+0x1e0/0x1490
>> [ 415.141125] ? do_syscall_64+0x1e0/0x1490
>> [ 415.141127] ? irqentry_exit+0x140/0x7e0
>> [ 415.141129] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>
>> [...]
>
> Applied to 7.0/scsi-fixes, thanks!
>
> [1/1] scsi: storvsc: Fix scheduling while atomic on PREEMPT_RT
> https://git.kernel.org/mkp/scsi/c/57297736c082
>
Should it be here then already?
https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git/log/?h=7.0/scsi-fixes
Sorry, just trying to understand the process.
Jan
--
Siemens AG, Foundational Technologies
Linux Expert Center
^ permalink raw reply
* Re: [PATCH net-next] net: mana: Expose page_pool stats via ethtool
From: Andrew Lunn @ 2026-02-27 15:11 UTC (permalink / raw)
To: Dipayaan Roy
Cc: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
kuba, pabeni, leon, longli, kotaranov, horms, shradhagupta,
ssengar, ernis, shirazsaleem, linux-hyperv, netdev, linux-kernel,
linux-rdma, dipayanroy
In-Reply-To: <aaFmRqjjOuPIEo5x@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net>
> +static void mana_get_page_pool_stats(struct net_device *ndev, u64 *data)
> +{
> +#ifdef CONFIG_PAGE_POOL_STATS
> + struct mana_port_context *apc = netdev_priv(ndev);
> + unsigned int num_queues = apc->num_queues;
> + struct page_pool_stats pp_stats = {};
> + int q;
> +
> + for (q = 0; q < num_queues; q++) {
> + if (!apc->rxqs[q] || !apc->rxqs[q]->page_pool)
> + continue;
> +
> + page_pool_get_stats(apc->rxqs[q]->page_pool, &pp_stats);
> + }
> +
> + page_pool_ethtool_stats_get(data, &pp_stats);
> +#endif /* CONFIG_PAGE_POOL_STATS */
You should not need this #ifdef. The stubs should make the code do
sensible things if CONFIG_PAGE_POOL_STATS is not enabled.
Andrew
^ permalink raw reply
* [PATCH v1 4/4] page_reporting: change PAGE_REPORTING_DEFAULT_ORDER to -1
From: Yuvraj Sakshith @ 2026-02-27 14:06 UTC (permalink / raw)
To: akpm
Cc: mst, david, kys, haiyangz, wei.liu, decui, longli, jasowang,
xuanzhuo, eperezma, lorenzo.stoakes, Liam.Howlett, vbabka, rppt,
surenb, mhocko, jackmanb, hannes, ziy, linux-hyperv,
virtualization, linux-mm, linux-kernel
In-Reply-To: <20260227140655.360696-1-yuvraj.sakshith@oss.qualcomm.com>
PAGE_REPORTING_DEFAULT_ORDER is now set to zero. This means,
pages of order zero cannot be reported to a client/driver -- as zero
is used to signal a fallback to MAX_PAGE_ORDER.
Change PAGE_REPORTING_DEFAULT_ORDER to (-1),
so that zero can be used as a valid order with which pages can
be reported.
Signed-off-by: Yuvraj Sakshith <yuvraj.sakshith@oss.qualcomm.com>
---
include/linux/page_reporting.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/page_reporting.h b/include/linux/page_reporting.h
index a7e3e30f2..3eb3e26d8 100644
--- a/include/linux/page_reporting.h
+++ b/include/linux/page_reporting.h
@@ -7,7 +7,7 @@
/* This value should always be a power of 2, see page_reporting_cycle() */
#define PAGE_REPORTING_CAPACITY 32
-#define PAGE_REPORTING_DEFAULT_ORDER 0
+#define PAGE_REPORTING_DEFAULT_ORDER (-1)
struct page_reporting_dev_info {
/* function that alters pages to make them "reported" */
--
2.34.1
^ permalink raw reply related
* [PATCH v1 3/4] hv_balloon: set default page reporting order
From: Yuvraj Sakshith @ 2026-02-27 14:06 UTC (permalink / raw)
To: akpm
Cc: mst, david, kys, haiyangz, wei.liu, decui, longli, jasowang,
xuanzhuo, eperezma, lorenzo.stoakes, Liam.Howlett, vbabka, rppt,
surenb, mhocko, jackmanb, hannes, ziy, linux-hyperv,
virtualization, linux-mm, linux-kernel
In-Reply-To: <20260227140655.360696-1-yuvraj.sakshith@oss.qualcomm.com>
Explicitly mention page reporting order to be set to
default value using PAGE_REPORTING_DEFAULT_ORDER fallback
value.
Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Yuvraj Sakshith <yuvraj.sakshith@oss.qualcomm.com>
---
drivers/hv/hv_balloon.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
index 2b4080e51..3d6bd9936 100644
--- a/drivers/hv/hv_balloon.c
+++ b/drivers/hv/hv_balloon.c
@@ -1663,7 +1663,7 @@ static void enable_page_reporting(void)
* We let the page_reporting_order parameter decide the order
* in the page_reporting code
*/
- dm_device.pr_dev_info.order = 0;
+ dm_device.pr_dev_info.order = PAGE_REPORTING_DEFAULT_ORDER;
ret = page_reporting_register(&dm_device.pr_dev_info);
if (ret < 0) {
dm_device.pr_dev_info.report = NULL;
--
2.34.1
^ permalink raw reply related
* [PATCH v1 2/4] virtio_balloon: set default page reporting order
From: Yuvraj Sakshith @ 2026-02-27 14:06 UTC (permalink / raw)
To: akpm
Cc: mst, david, kys, haiyangz, wei.liu, decui, longli, jasowang,
xuanzhuo, eperezma, lorenzo.stoakes, Liam.Howlett, vbabka, rppt,
surenb, mhocko, jackmanb, hannes, ziy, linux-hyperv,
virtualization, linux-mm, linux-kernel
In-Reply-To: <20260227140655.360696-1-yuvraj.sakshith@oss.qualcomm.com>
virtio_balloon page reporting order is set to MAX_PAGE_ORDER implicitly
as vb->prdev.order is never initialised and is auto-set to zero.
Explicitly mention usage of default page order by making use of
PAGE_REPORTING_DEFAULT ORDER fallback value.
Signed-off-by: Yuvraj Sakshith <yuvraj.sakshith@oss.qualcomm.com>
---
drivers/virtio/virtio_balloon.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 74fe59f5a..0616c03b2 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -1044,6 +1044,8 @@ static int virtballoon_probe(struct virtio_device *vdev)
goto out_unregister_oom;
}
+ vb->pr_dev_info.order = PAGE_REPORTING_DEFAULT_ORDER;
+
/*
* The default page reporting order is @pageblock_order, which
* corresponds to 512MB in size on ARM64 when 64KB base page
--
2.34.1
^ permalink raw reply related
* [PATCH v1 1/4] page_reporting: add PAGE_REPORTING_DEFAULT_ORDER
From: Yuvraj Sakshith @ 2026-02-27 14:06 UTC (permalink / raw)
To: akpm
Cc: mst, david, kys, haiyangz, wei.liu, decui, longli, jasowang,
xuanzhuo, eperezma, lorenzo.stoakes, Liam.Howlett, vbabka, rppt,
surenb, mhocko, jackmanb, hannes, ziy, linux-hyperv,
virtualization, linux-mm, linux-kernel
In-Reply-To: <20260227140655.360696-1-yuvraj.sakshith@oss.qualcomm.com>
Drivers can pass order of pages to be reported while
registering itself. Today, this is a magic number, 0.
Label this with PAGE_REPORTING_DEFAULT_ORDER and
check for it when the driver is being registered.
Signed-off-by: Yuvraj Sakshith <yuvraj.sakshith@oss.qualcomm.com>
---
include/linux/page_reporting.h | 1 +
mm/page_reporting.c | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/linux/page_reporting.h b/include/linux/page_reporting.h
index fe648dfa3..a7e3e30f2 100644
--- a/include/linux/page_reporting.h
+++ b/include/linux/page_reporting.h
@@ -7,6 +7,7 @@
/* This value should always be a power of 2, see page_reporting_cycle() */
#define PAGE_REPORTING_CAPACITY 32
+#define PAGE_REPORTING_DEFAULT_ORDER 0
struct page_reporting_dev_info {
/* function that alters pages to make them "reported" */
diff --git a/mm/page_reporting.c b/mm/page_reporting.c
index e4c428e61..9ad4fc3f8 100644
--- a/mm/page_reporting.c
+++ b/mm/page_reporting.c
@@ -370,7 +370,8 @@ int page_reporting_register(struct page_reporting_dev_info *prdev)
*/
if (page_reporting_order == -1) {
- if (prdev->order > 0 && prdev->order <= MAX_PAGE_ORDER)
+ if (prdev->order != PAGE_REPORTING_DEFAULT_ORDER &&
+ prdev->order <= MAX_PAGE_ORDER)
page_reporting_order = prdev->order;
else
page_reporting_order = pageblock_order;
--
2.34.1
^ permalink raw reply related
* [PATCH v1 0/4] Allow order zero pages in page reporting
From: Yuvraj Sakshith @ 2026-02-27 14:06 UTC (permalink / raw)
To: akpm
Cc: mst, david, kys, haiyangz, wei.liu, decui, longli, jasowang,
xuanzhuo, eperezma, lorenzo.stoakes, Liam.Howlett, vbabka, rppt,
surenb, mhocko, jackmanb, hannes, ziy, linux-hyperv,
virtualization, linux-mm, linux-kernel
Today, page reporting sets page_reporting_order in two ways:
(1) page_reporting.page_reporting_order cmdline parameter
(2) Driver can pass order while registering itself.
In both cases, order zero is ignored by free page reporting
because it is used to set page_reporting_order to a default
value, like MAX_PAGE_ORDER.
In some cases we might want page_reporting_order to be zero.
For instance, when virtio-balloon runs inside a guest with
tiny memory (say, 16MB), it might not be able to find a order 1 page
(or in the worst case order MAX_PAGE_ORDER page) after some uptime.
Page reporting should be able to return order zero pages back for
optimal memory relinquishment.
This patch changes the default fallback value from '0' to '-1' in
all possible clients of free page reporting (hv_balloon and
virtio-balloon) together with allowing '0' as a valid order in
page_reporting_register().
Changes in v1:
- Introduce PAGE_REPORTING_DEFAULT_ORDER macro (initially set to 0).
- Make use of new macro in drivers (hv_balloon and virtio-balloon)
working with page reporting.
- Change PAGE_REPORTING_DEFAULT_ORDER to -1 as zero is a valid
page order that can be requested.
Yuvraj Sakshith (3):
mm/page_reporting: Allow zero page_reporting_order
hv_balloon: Change default page reporting order
virtio_balloon: Set pr_dev.order to new default
drivers/hv/hv_balloon.c | 2 +-
drivers/virtio/virtio_balloon.c | 14 ++++++++++++++
mm/page_reporting.c | 2 +-
3 files changed, 16 insertions(+), 2 deletions(-)
--
2.34.1
^ permalink raw reply
* Re: [PATCH net v2] net: mana: Ring doorbell at 4 CQ wraparounds
From: Vadim Fedorenko @ 2026-02-27 10:53 UTC (permalink / raw)
To: Long Li, K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Andrew Lunn, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Shradha Gupta, Erni Sri Satya Vennela, linux-hyperv, netdev,
linux-kernel, stable
In-Reply-To: <20260226192833.1050807-1-longli@microsoft.com>
On 26/02/2026 19:28, Long Li wrote:
> MANA hardware requires at least one doorbell ring every 8 wraparounds
> of the CQ. The driver rings the doorbell as a form of flow control to
> inform hardware that CQEs have been consumed.
>
> The NAPI poll functions mana_poll_tx_cq() and mana_poll_rx_cq() can
> poll up to CQE_POLLING_BUFFER (512) completions per call. If the CQ
> has fewer than 512 entries, a single poll call can process more than
> 4 wraparounds without ringing the doorbell. The doorbell threshold
> check also uses ">" instead of ">=", delaying the ring by one extra
> CQE beyond 4 wraparounds. Combined, these issues can cause the driver
> to exceed the 8-wraparound hardware limit, leading to missed
> completions and stalled queues.
>
> Fix this by capping the number of CQEs polled per call to 4 wraparounds
> of the CQ in both TX and RX paths. Also change the doorbell threshold
> from ">" to ">=" so the doorbell is rung as soon as 4 wraparounds are
> reached.
>
> Cc: stable@vger.kernel.org
> Fixes: 58a63729c957 ("net: mana: Fix doorbell out of order violation and avoid unnecessary doorbell rings")
> Signed-off-by: Long Li <longli@microsoft.com>
> ---
> v2: Use min() instead of min_t(u32, ...) since queue_size is already u32
> drivers/net/ethernet/microsoft/mana/mana_en.c | 23 +++++++++++++++----
> 1 file changed, 18 insertions(+), 5 deletions(-)
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
^ permalink raw reply
* [PATCH net-next] net: mana: Force full-page RX buffers for 4K page size on specific systems.
From: Dipayaan Roy @ 2026-02-27 10:15 UTC (permalink / raw)
To: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
kuba, pabeni, leon, longli, kotaranov, horms, shradhagupta,
ssengar, ernis, shirazsaleem, linux-hyperv, netdev, linux-kernel,
linux-rdma, dipayanroy
On certain systems configured with 4K PAGE_SIZE, utilizing page_pool
fragments for RX buffers results in a significant throughput regression.
Profiling reveals that this regression correlates with high overhead in the
fragment allocation and reference counting paths on these specific
platforms, rendering the multi-buffer-per-page strategy counterproductive.
To mitigate this, bypass the page_pool fragment path and force a single RX
packet per page allocation when all the following conditions are met:
1. The system is configured with a 4K PAGE_SIZE.
2. A processor-specific quirk is detected via SMBIOS Type 4 data.
This approach restores expected line-rate performance by ensuring
predictable RX refill behavior on affected hardware.
There is no behavioral change for systems using larger page sizes
(16K/64K), or platforms where this processor-specific quirk do not
apply.
Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
---
.../net/ethernet/microsoft/mana/gdma_main.c | 120 ++++++++++++++++++
drivers/net/ethernet/microsoft/mana/mana_en.c | 23 +++-
include/net/mana/gdma.h | 10 ++
3 files changed, 151 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c
index 0055c231acf6..26bbe736a770 100644
--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c
+++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c
@@ -9,6 +9,7 @@
#include <linux/msi.h>
#include <linux/irqdomain.h>
#include <linux/export.h>
+#include <linux/dmi.h>
#include <net/mana/mana.h>
#include <net/mana/hw_channel.h>
@@ -1955,6 +1956,115 @@ static bool mana_is_pf(unsigned short dev_id)
return dev_id == MANA_PF_DEVICE_ID;
}
+/*
+ * Table for Processor Version strings found from SMBIOS Type 4 information,
+ * for processors that needs to force single RX buffer per page quirk for
+ * meeting line rate performance with ARM64 + 4K pages.
+ * Note: These strings are exactly matched with version fetched from SMBIOS.
+ */
+static const char * const mana_single_rxbuf_per_page_quirk_tbl[] = {
+ "Cobalt 200",
+};
+
+static const char *smbios_get_string(const struct dmi_header *hdr, u8 idx)
+{
+ const u8 *start, *end;
+ u8 i;
+
+ /* Indexing starts from 1. */
+ if (!idx)
+ return NULL;
+
+ start = (const u8 *)hdr + hdr->length;
+ end = start + SMBIOS_STR_AREA_MAX;
+
+ for (i = 1; i < idx; i++) {
+ while (start < end && *start)
+ start++;
+ if (start < end)
+ start++;
+ if (start + 1 < end && start[0] == 0 && start[1] == 0)
+ return NULL;
+ }
+
+ if (start >= end || *start == 0)
+ return NULL;
+
+ return (const char *)start;
+}
+
+/* On some systems with 4K PAGE_SIZE, page_pool RX fragments can
+ * trigger a throughput regression. Hence identify those processors
+ * from the extracted SMBIOS table and apply the quirk to forces one
+ * RX buffer per page to avoid the fragment allocation/refcounting
+ * overhead in the RX refill path for those processors only.
+ */
+static bool mana_needs_single_rxbuf_per_page(struct gdma_context *gc)
+{
+ int i = 0;
+ const char *ver = gc->processor_version;
+
+ if (!ver)
+ return false;
+
+ if (PAGE_SIZE != SZ_4K)
+ return false;
+
+ while (i < ARRAY_SIZE(mana_single_rxbuf_per_page_quirk_tbl)) {
+ if (!strcmp(ver, mana_single_rxbuf_per_page_quirk_tbl[i]))
+ return true;
+ i++;
+ }
+
+ return false;
+}
+
+static void mana_get_proc_ver_from_smbios(const struct dmi_header *hdr,
+ void *data)
+{
+ struct gdma_context *gc = data;
+ const char *ver_str;
+ u8 idx;
+
+ /* We are only looking for Type 4: Processor Information */
+ if (hdr->type != SMBIOS_TYPE_4_PROCESSOR_INFO)
+ return;
+
+ /* Ensure the record is long enough to contain the Processor Version
+ * field
+ */
+ if (hdr->length <= SMBIOS_TYPE4_PROC_VERSION_OFFSET)
+ return;
+
+ /* The 'Processor Version' string is located at index pointed by
+ * SMBIOS_TYPE4_PROC_VERSION_OFFSET. If found make a copy of it.
+ * There could be multiple Type 4 tables so read and copy the
+ * processor version found the first time.
+ */
+ idx = ((const u8 *)hdr)[SMBIOS_TYPE4_PROC_VERSION_OFFSET];
+ ver_str = smbios_get_string(hdr, idx);
+ if (ver_str && !gc->processor_version)
+ gc->processor_version = kstrdup(ver_str, GFP_KERNEL);
+}
+
+/* Check and initialize all processor optimizations/quirks here */
+static bool mana_init_processor_optimization(struct gdma_context *gc)
+{
+ bool opt_initialized = false;
+
+ gc->processor_version = NULL;
+ dmi_walk(mana_get_proc_ver_from_smbios, gc);
+ if (!gc->processor_version)
+ return false;
+
+ if (mana_needs_single_rxbuf_per_page(gc)) {
+ gc->force_full_page_rx_buffer = true;
+ opt_initialized = true;
+ }
+
+ return opt_initialized;
+}
+
static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct gdma_context *gc;
@@ -2009,6 +2119,11 @@ static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
gc->mana_pci_debugfs = debugfs_create_dir(pci_slot_name(pdev->slot),
mana_debugfs_root);
+ if (mana_init_processor_optimization(gc))
+ dev_info(&pdev->dev,
+ "Processor specific optimization initialized on: %s\n",
+ gc->processor_version);
+
err = mana_gd_setup(pdev);
if (err)
goto unmap_bar;
@@ -2051,6 +2166,8 @@ static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_iounmap(pdev, bar0_va);
free_gc:
pci_set_drvdata(pdev, NULL);
+ kfree(gc->processor_version);
+ gc->processor_version = NULL;
vfree(gc);
release_region:
pci_release_regions(pdev);
@@ -2106,6 +2223,9 @@ static void mana_gd_remove(struct pci_dev *pdev)
pci_iounmap(pdev, gc->bar0_va);
+ kfree(gc->processor_version);
+ gc->processor_version = NULL;
+
vfree(gc);
pci_release_regions(pdev);
diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
index 91c418097284..a53a8921050b 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -748,6 +748,26 @@ static void *mana_get_rxbuf_pre(struct mana_rxq *rxq, dma_addr_t *da)
return va;
}
+static inline bool
+mana_use_single_rxbuf_per_page(struct mana_port_context *apc, u32 mtu)
+{
+ struct gdma_context *gc = apc->ac->gdma_dev->gdma_context;
+
+ /* On some systems with 4K PAGE_SIZE, page_pool RX fragments can
+ * trigger a throughput regression. Hence forces one RX buffer per page
+ * to avoid the fragment allocation/refcounting overhead in the RX
+ * refill path for those processors only.
+ */
+ if (gc->force_full_page_rx_buffer)
+ return true;
+
+ /* For xdp and jumbo frames make sure only one packet fits per page. */
+ if (mtu + MANA_RXBUF_PAD > PAGE_SIZE / 2 || mana_xdp_get(apc))
+ return true;
+
+ return false;
+}
+
/* Get RX buffer's data size, alloc size, XDP headroom based on MTU */
static void mana_get_rxbuf_cfg(struct mana_port_context *apc,
int mtu, u32 *datasize, u32 *alloc_size,
@@ -758,8 +778,7 @@ static void mana_get_rxbuf_cfg(struct mana_port_context *apc,
/* Calculate datasize first (consistent across all cases) */
*datasize = mtu + ETH_HLEN;
- /* For xdp and jumbo frames make sure only one packet fits per page */
- if (mtu + MANA_RXBUF_PAD > PAGE_SIZE / 2 || mana_xdp_get(apc)) {
+ if (mana_use_single_rxbuf_per_page(apc, mtu)) {
if (mana_xdp_get(apc)) {
*headroom = XDP_PACKET_HEADROOM;
*alloc_size = PAGE_SIZE;
diff --git a/include/net/mana/gdma.h b/include/net/mana/gdma.h
index a59bd4035a99..0ef2d6ac5203 100644
--- a/include/net/mana/gdma.h
+++ b/include/net/mana/gdma.h
@@ -9,6 +9,14 @@
#include "shm_channel.h"
+#define SMBIOS_STR_AREA_MAX 4096
+
+/* SMBIOS Type 4: Processor Information table */
+#define SMBIOS_TYPE_4_PROCESSOR_INFO 4
+
+/* Byte offset containing the Processor Version string number.*/
+#define SMBIOS_TYPE4_PROC_VERSION_OFFSET 0x10
+
#define GDMA_STATUS_MORE_ENTRIES 0x00000105
#define GDMA_STATUS_CMD_UNSUPPORTED 0xffffffff
@@ -436,6 +444,8 @@ struct gdma_context {
struct workqueue_struct *service_wq;
unsigned long flags;
+ u8 *processor_version;
+ bool force_full_page_rx_buffer;
};
static inline bool mana_gd_is_mana(struct gdma_dev *gd)
--
2.43.0
^ permalink raw reply related
* [PATCH net-next] net: mana: Expose page_pool stats via ethtool
From: Dipayaan Roy @ 2026-02-27 9:39 UTC (permalink / raw)
To: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
kuba, pabeni, leon, longli, kotaranov, horms, shradhagupta,
ssengar, ernis, shirazsaleem, linux-hyperv, netdev, linux-kernel,
linux-rdma, dipayanroy
MANA relies on page_pool for RX buffers, and the buffer refill paths
can behave quite differently across architectures and configurations (e.g.
base page size, fragment vs full-page usage). This makes it harder to
understand and compare RX buffer behavior when investigating performance
and memory differences across platforms.
Wire up the generic page_pool ethtool stats helpers and report
page_pool allocation/recycle statistics via ethtool -S when
CONFIG_PAGE_POOL_STATS is enabled. The counters are exposed with the
standard "rx_pp_*" names, for example:
rx_pp_alloc_fast
rx_pp_alloc_slow
rx_pp_alloc_slow_ho
rx_pp_alloc_empty
rx_pp_alloc_refill
rx_pp_alloc_waive
rx_pp_recycle_cached
rx_pp_recycle_cache_full
rx_pp_recycle_ring
rx_pp_recycle_ring_full
rx_pp_recycle_released_ref
Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
---
.../ethernet/microsoft/mana/mana_ethtool.c | 30 +++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c
index f2d220b371b5..8fec74cdd3c3 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c
@@ -6,6 +6,7 @@
#include <linux/ethtool.h>
#include <net/mana/mana.h>
+#include <net/page_pool/helpers.h>
struct mana_stats_desc {
char name[ETH_GSTRING_LEN];
@@ -143,8 +144,10 @@ static int mana_get_sset_count(struct net_device *ndev, int stringset)
if (stringset != ETH_SS_STATS)
return -EINVAL;
- return ARRAY_SIZE(mana_eth_stats) + ARRAY_SIZE(mana_phy_stats) + ARRAY_SIZE(mana_hc_stats) +
- num_queues * (MANA_STATS_RX_COUNT + MANA_STATS_TX_COUNT);
+ return ARRAY_SIZE(mana_eth_stats) + ARRAY_SIZE(mana_phy_stats) +
+ ARRAY_SIZE(mana_hc_stats) +
+ num_queues * (MANA_STATS_RX_COUNT + MANA_STATS_TX_COUNT) +
+ page_pool_ethtool_stats_get_count();
}
static void mana_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
@@ -185,6 +188,27 @@ static void mana_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
ethtool_sprintf(&data, "tx_%d_csum_partial", i);
ethtool_sprintf(&data, "tx_%d_mana_map_err", i);
}
+
+ page_pool_ethtool_stats_get_strings(data);
+}
+
+static void mana_get_page_pool_stats(struct net_device *ndev, u64 *data)
+{
+#ifdef CONFIG_PAGE_POOL_STATS
+ struct mana_port_context *apc = netdev_priv(ndev);
+ unsigned int num_queues = apc->num_queues;
+ struct page_pool_stats pp_stats = {};
+ int q;
+
+ for (q = 0; q < num_queues; q++) {
+ if (!apc->rxqs[q] || !apc->rxqs[q]->page_pool)
+ continue;
+
+ page_pool_get_stats(apc->rxqs[q]->page_pool, &pp_stats);
+ }
+
+ page_pool_ethtool_stats_get(data, &pp_stats);
+#endif /* CONFIG_PAGE_POOL_STATS */
}
static void mana_get_ethtool_stats(struct net_device *ndev,
@@ -280,6 +304,8 @@ static void mana_get_ethtool_stats(struct net_device *ndev,
data[i++] = csum_partial;
data[i++] = mana_map_err;
}
+
+ mana_get_page_pool_stats(ndev, &data[i]);
}
static u32 mana_get_rx_ring_count(struct net_device *ndev)
--
2.43.0
^ permalink raw reply related
* [PATCH net-next, v2] net: mana: Trigger VF reset/recovery on health check failure due to HWC timeout
From: Dipayaan Roy @ 2026-02-27 8:15 UTC (permalink / raw)
To: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
kuba, pabeni, leon, longli, kotaranov, horms, shradhagupta,
ssengar, ernis, shirazsaleem, linux-hyperv, netdev, linux-kernel,
linux-rdma, dipayanroy
The GF stats periodic query is used as mechanism to monitor HWC health
check. If this HWC command times out, it is a strong indication that
the device/SoC is in a faulty state and requires recovery.
Today, when a timeout is detected, the driver marks
hwc_timeout_occurred, clears cached stats, and stops rescheduling the
periodic work. However, the device itself is left in the same failing
state.
Extend the timeout handling path to trigger the existing MANA VF
recovery service by queueing a GDMA_EQE_HWC_RESET_REQUEST work item.
This is expected to initiate the appropriate recovery flow by suspende
resume first and if it fails then trigger a bus rescan.
This change is intentionally limited to HWC command timeouts and does
not trigger recovery for errors reported by the SoC as a normal command
response.
Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
---
Changes in v2:
- Added common helper, proper clearing of gc flags.
---
---
.../net/ethernet/microsoft/mana/gdma_main.c | 65 ++++++++++---------
drivers/net/ethernet/microsoft/mana/mana_en.c | 9 ++-
include/net/mana/gdma.h | 16 ++++-
3 files changed, 55 insertions(+), 35 deletions(-)
diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c
index 37d2f108a839..aef8612b73cb 100644
--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c
+++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c
@@ -490,15 +490,9 @@ static void mana_serv_reset(struct pci_dev *pdev)
dev_info(&pdev->dev, "MANA reset cycle completed\n");
out:
- gc->in_service = false;
+ clear_bit(GC_IN_SERVICE, &gc->flags);
}
-struct mana_serv_work {
- struct work_struct serv_work;
- struct pci_dev *pdev;
- enum gdma_eqe_type type;
-};
-
static void mana_do_service(enum gdma_eqe_type type, struct pci_dev *pdev)
{
switch (type) {
@@ -558,12 +552,42 @@ static void mana_serv_func(struct work_struct *w)
module_put(THIS_MODULE);
}
+int mana_schedule_serv_work(struct gdma_context *gc, enum gdma_eqe_type type)
+{
+ struct mana_serv_work *mns_wk;
+
+ if (test_and_set_bit(GC_IN_SERVICE, &gc->flags)) {
+ dev_info(gc->dev, "Already in service\n");
+ return -EBUSY;
+ }
+
+ if (!try_module_get(THIS_MODULE)) {
+ dev_info(gc->dev, "Module is unloading\n");
+ clear_bit(GC_IN_SERVICE, &gc->flags);
+ return -ENODEV;
+ }
+
+ mns_wk = kzalloc(sizeof(*mns_wk), GFP_ATOMIC);
+ if (!mns_wk) {
+ module_put(THIS_MODULE);
+ clear_bit(GC_IN_SERVICE, &gc->flags);
+ return -ENOMEM;
+ }
+
+ dev_info(gc->dev, "Start MANA service type:%d\n", type);
+ mns_wk->pdev = to_pci_dev(gc->dev);
+ mns_wk->type = type;
+ pci_dev_get(mns_wk->pdev);
+ INIT_WORK(&mns_wk->serv_work, mana_serv_func);
+ schedule_work(&mns_wk->serv_work);
+ return 0;
+}
+
static void mana_gd_process_eqe(struct gdma_queue *eq)
{
u32 head = eq->head % (eq->queue_size / GDMA_EQE_SIZE);
struct gdma_context *gc = eq->gdma_dev->gdma_context;
struct gdma_eqe *eq_eqe_ptr = eq->queue_mem_ptr;
- struct mana_serv_work *mns_wk;
union gdma_eqe_info eqe_info;
enum gdma_eqe_type type;
struct gdma_event event;
@@ -623,30 +647,7 @@ static void mana_gd_process_eqe(struct gdma_queue *eq)
"Service is to be processed in probe\n");
break;
}
-
- if (gc->in_service) {
- dev_info(gc->dev, "Already in service\n");
- break;
- }
-
- if (!try_module_get(THIS_MODULE)) {
- dev_info(gc->dev, "Module is unloading\n");
- break;
- }
-
- mns_wk = kzalloc_obj(*mns_wk, GFP_ATOMIC);
- if (!mns_wk) {
- module_put(THIS_MODULE);
- break;
- }
-
- dev_info(gc->dev, "Start MANA service type:%d\n", type);
- gc->in_service = true;
- mns_wk->pdev = to_pci_dev(gc->dev);
- mns_wk->type = type;
- pci_dev_get(mns_wk->pdev);
- INIT_WORK(&mns_wk->serv_work, mana_serv_func);
- schedule_work(&mns_wk->serv_work);
+ mana_schedule_serv_work(gc, type);
break;
default:
diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
index 933e9d681ded..56ee993e3a43 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -875,7 +875,7 @@ static void mana_tx_timeout(struct net_device *netdev, unsigned int txqueue)
struct gdma_context *gc = ac->gdma_dev->gdma_context;
/* Already in service, hence tx queue reset is not required.*/
- if (gc->in_service)
+ if (test_bit(GC_IN_SERVICE, &gc->flags))
return;
/* Note: If there are pending queue reset work for this port(apc),
@@ -3525,6 +3525,7 @@ static void mana_gf_stats_work_handler(struct work_struct *work)
{
struct mana_context *ac =
container_of(to_delayed_work(work), struct mana_context, gf_stats_work);
+ struct gdma_context *gc = ac->gdma_dev->gdma_context;
int err;
err = mana_query_gf_stats(ac);
@@ -3532,6 +3533,12 @@ static void mana_gf_stats_work_handler(struct work_struct *work)
/* HWC timeout detected - reset stats and stop rescheduling */
ac->hwc_timeout_occurred = true;
memset(&ac->hc_stats, 0, sizeof(ac->hc_stats));
+ dev_warn(gc->dev,
+ "Gf stats wk handler: gf stats query timed out.\n");
+ /* As HWC timed out, indicating a faulty HW state and needs a
+ * reset.
+ */
+ mana_schedule_serv_work(gc, GDMA_EQE_HWC_RESET_REQUEST);
return;
}
schedule_delayed_work(&ac->gf_stats_work, MANA_GF_STATS_PERIOD);
diff --git a/include/net/mana/gdma.h b/include/net/mana/gdma.h
index 766f4fb25e26..ec17004b10c0 100644
--- a/include/net/mana/gdma.h
+++ b/include/net/mana/gdma.h
@@ -215,6 +215,12 @@ enum gdma_page_type {
#define GDMA_INVALID_DMA_REGION 0
+struct mana_serv_work {
+ struct work_struct serv_work;
+ struct pci_dev *pdev;
+ enum gdma_eqe_type type;
+};
+
struct gdma_mem_info {
struct device *dev;
@@ -386,6 +392,7 @@ struct gdma_irq_context {
enum gdma_context_flags {
GC_PROBE_SUCCEEDED = 0,
+ GC_IN_SERVICE = 1,
};
struct gdma_context {
@@ -411,7 +418,6 @@ struct gdma_context {
u32 test_event_eq_id;
bool is_pf;
- bool in_service;
phys_addr_t bar0_pa;
void __iomem *bar0_va;
@@ -473,6 +479,8 @@ int mana_gd_poll_cq(struct gdma_queue *cq, struct gdma_comp *comp, int num_cqe);
void mana_gd_ring_cq(struct gdma_queue *cq, u8 arm_bit);
+int mana_schedule_serv_work(struct gdma_context *gc, enum gdma_eqe_type type);
+
struct gdma_wqe {
u32 reserved :24;
u32 last_vbytes :8;
@@ -615,6 +623,9 @@ enum {
/* Driver can handle hardware recovery events during probe */
#define GDMA_DRV_CAP_FLAG_1_PROBE_RECOVERY BIT(22)
+/* Driver supports self recovery on Hardware Channel timeouts */
+#define GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECOVERY BIT(25)
+
#define GDMA_DRV_CAP_FLAGS1 \
(GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT | \
GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX | \
@@ -628,7 +639,8 @@ enum {
GDMA_DRV_CAP_FLAG_1_PERIODIC_STATS_QUERY | \
GDMA_DRV_CAP_FLAG_1_SKB_LINEARIZE | \
GDMA_DRV_CAP_FLAG_1_PROBE_RECOVERY | \
- GDMA_DRV_CAP_FLAG_1_HANDLE_STALL_SQ_RECOVERY)
+ GDMA_DRV_CAP_FLAG_1_HANDLE_STALL_SQ_RECOVERY | \
+ GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECOVERY)
#define GDMA_DRV_CAP_FLAGS2 0
--
2.34.1
^ permalink raw reply related
* Re: [PATCH] mshv: Introduce tracing support
From: Dan Carpenter @ 2026-02-27 8:11 UTC (permalink / raw)
To: oe-kbuild, Stanislav Kinsburskii, kys, haiyangz, wei.liu, decui,
longli
Cc: lkp, oe-kbuild-all, linux-hyperv, linux-kernel
In-Reply-To: <177213348504.92223.5330421592610811972.stgit@skinsburskii-cloud-desktop.internal.cloudapp.net>
Hi Stanislav,
kernel test robot noticed the following build warnings:
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Stanislav-Kinsburskii/mshv-Introduce-tracing-support/20260227-031942
base: linus/master
patch link: https://lore.kernel.org/r/177213348504.92223.5330421592610811972.stgit%40skinsburskii-cloud-desktop.internal.cloudapp.net
patch subject: [PATCH] mshv: Introduce tracing support
config: x86_64-randconfig-161-20260227 (https://download.01.org/0day-ci/archive/20260227/202602271528.jLhA59mn-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
smatch version: v0.5.0-8994-gd50c5a4c
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
| Closes: https://lore.kernel.org/r/202602271528.jLhA59mn-lkp@intel.com/
New smatch warnings:
drivers/hv/mshv_root_main.c:1177 mshv_partition_ioctl_create_vp() error: we previously assumed 'vp' could be null (see line 1110)
drivers/hv/mshv_root_main.c:1177 mshv_partition_ioctl_create_vp() error: dereferencing freed memory 'vp' (line 1157)
vim +/vp +1177 drivers/hv/mshv_root_main.c
621191d709b148 Nuno Das Neves 2025-03-14 1057 static long
621191d709b148 Nuno Das Neves 2025-03-14 1058 mshv_partition_ioctl_create_vp(struct mshv_partition *partition,
621191d709b148 Nuno Das Neves 2025-03-14 1059 void __user *arg)
621191d709b148 Nuno Das Neves 2025-03-14 1060 {
621191d709b148 Nuno Das Neves 2025-03-14 1061 struct mshv_create_vp args;
621191d709b148 Nuno Das Neves 2025-03-14 1062 struct mshv_vp *vp;
19c515c27cee3b Jinank Jain 2025-10-10 1063 struct page *intercept_msg_page, *register_page, *ghcb_page;
2de4516aa8f726 Stanislav Kinsburskii 2026-01-28 1064 struct hv_stats_page *stats_pages[2];
621191d709b148 Nuno Das Neves 2025-03-14 1065 long ret;
621191d709b148 Nuno Das Neves 2025-03-14 1066
621191d709b148 Nuno Das Neves 2025-03-14 1067 if (copy_from_user(&args, arg, sizeof(args)))
621191d709b148 Nuno Das Neves 2025-03-14 1068 return -EFAULT;
621191d709b148 Nuno Das Neves 2025-03-14 1069
621191d709b148 Nuno Das Neves 2025-03-14 1070 if (args.vp_index >= MSHV_MAX_VPS)
621191d709b148 Nuno Das Neves 2025-03-14 1071 return -EINVAL;
621191d709b148 Nuno Das Neves 2025-03-14 1072
621191d709b148 Nuno Das Neves 2025-03-14 1073 if (partition->pt_vp_array[args.vp_index])
621191d709b148 Nuno Das Neves 2025-03-14 1074 return -EEXIST;
621191d709b148 Nuno Das Neves 2025-03-14 1075
621191d709b148 Nuno Das Neves 2025-03-14 1076 ret = hv_call_create_vp(NUMA_NO_NODE, partition->pt_id, args.vp_index,
621191d709b148 Nuno Das Neves 2025-03-14 1077 0 /* Only valid for root partition VPs */);
621191d709b148 Nuno Das Neves 2025-03-14 1078 if (ret)
621191d709b148 Nuno Das Neves 2025-03-14 1079 return ret;
621191d709b148 Nuno Das Neves 2025-03-14 1080
19c515c27cee3b Jinank Jain 2025-10-10 1081 ret = hv_map_vp_state_page(partition->pt_id, args.vp_index,
621191d709b148 Nuno Das Neves 2025-03-14 1082 HV_VP_STATE_PAGE_INTERCEPT_MESSAGE,
19c515c27cee3b Jinank Jain 2025-10-10 1083 input_vtl_zero, &intercept_msg_page);
621191d709b148 Nuno Das Neves 2025-03-14 1084 if (ret)
621191d709b148 Nuno Das Neves 2025-03-14 1085 goto destroy_vp;
621191d709b148 Nuno Das Neves 2025-03-14 1086
621191d709b148 Nuno Das Neves 2025-03-14 1087 if (!mshv_partition_encrypted(partition)) {
19c515c27cee3b Jinank Jain 2025-10-10 1088 ret = hv_map_vp_state_page(partition->pt_id, args.vp_index,
621191d709b148 Nuno Das Neves 2025-03-14 1089 HV_VP_STATE_PAGE_REGISTERS,
19c515c27cee3b Jinank Jain 2025-10-10 1090 input_vtl_zero, ®ister_page);
621191d709b148 Nuno Das Neves 2025-03-14 1091 if (ret)
621191d709b148 Nuno Das Neves 2025-03-14 1092 goto unmap_intercept_message_page;
621191d709b148 Nuno Das Neves 2025-03-14 1093 }
621191d709b148 Nuno Das Neves 2025-03-14 1094
621191d709b148 Nuno Das Neves 2025-03-14 1095 if (mshv_partition_encrypted(partition) &&
621191d709b148 Nuno Das Neves 2025-03-14 1096 is_ghcb_mapping_available()) {
19c515c27cee3b Jinank Jain 2025-10-10 1097 ret = hv_map_vp_state_page(partition->pt_id, args.vp_index,
621191d709b148 Nuno Das Neves 2025-03-14 1098 HV_VP_STATE_PAGE_GHCB,
19c515c27cee3b Jinank Jain 2025-10-10 1099 input_vtl_normal, &ghcb_page);
621191d709b148 Nuno Das Neves 2025-03-14 1100 if (ret)
621191d709b148 Nuno Das Neves 2025-03-14 1101 goto unmap_register_page;
621191d709b148 Nuno Das Neves 2025-03-14 1102 }
621191d709b148 Nuno Das Neves 2025-03-14 1103
621191d709b148 Nuno Das Neves 2025-03-14 1104 ret = mshv_vp_stats_map(partition->pt_id, args.vp_index,
621191d709b148 Nuno Das Neves 2025-03-14 1105 stats_pages);
621191d709b148 Nuno Das Neves 2025-03-14 1106 if (ret)
621191d709b148 Nuno Das Neves 2025-03-14 1107 goto unmap_ghcb_page;
621191d709b148 Nuno Das Neves 2025-03-14 1108
bf4afc53b77aea Linus Torvalds 2026-02-21 1109 vp = kzalloc_obj(*vp);
621191d709b148 Nuno Das Neves 2025-03-14 @1110 if (!vp)
621191d709b148 Nuno Das Neves 2025-03-14 1111 goto unmap_stats_pages;
vp is NULL
621191d709b148 Nuno Das Neves 2025-03-14 1112
621191d709b148 Nuno Das Neves 2025-03-14 1113 vp->vp_partition = mshv_partition_get(partition);
621191d709b148 Nuno Das Neves 2025-03-14 1114 if (!vp->vp_partition) {
621191d709b148 Nuno Das Neves 2025-03-14 1115 ret = -EBADF;
621191d709b148 Nuno Das Neves 2025-03-14 1116 goto free_vp;
621191d709b148 Nuno Das Neves 2025-03-14 1117 }
621191d709b148 Nuno Das Neves 2025-03-14 1118
621191d709b148 Nuno Das Neves 2025-03-14 1119 mutex_init(&vp->vp_mutex);
621191d709b148 Nuno Das Neves 2025-03-14 1120 init_waitqueue_head(&vp->run.vp_suspend_queue);
621191d709b148 Nuno Das Neves 2025-03-14 1121 atomic64_set(&vp->run.vp_signaled_count, 0);
621191d709b148 Nuno Das Neves 2025-03-14 1122
621191d709b148 Nuno Das Neves 2025-03-14 1123 vp->vp_index = args.vp_index;
19c515c27cee3b Jinank Jain 2025-10-10 1124 vp->vp_intercept_msg_page = page_to_virt(intercept_msg_page);
621191d709b148 Nuno Das Neves 2025-03-14 1125 if (!mshv_partition_encrypted(partition))
621191d709b148 Nuno Das Neves 2025-03-14 1126 vp->vp_register_page = page_to_virt(register_page);
621191d709b148 Nuno Das Neves 2025-03-14 1127
621191d709b148 Nuno Das Neves 2025-03-14 1128 if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available())
621191d709b148 Nuno Das Neves 2025-03-14 1129 vp->vp_ghcb_page = page_to_virt(ghcb_page);
621191d709b148 Nuno Das Neves 2025-03-14 1130
621191d709b148 Nuno Das Neves 2025-03-14 1131 memcpy(vp->vp_stats_pages, stats_pages, sizeof(stats_pages));
621191d709b148 Nuno Das Neves 2025-03-14 1132
ff225ba9ad71c4 Nuno Das Neves 2026-01-28 1133 ret = mshv_debugfs_vp_create(vp);
ff225ba9ad71c4 Nuno Das Neves 2026-01-28 1134 if (ret)
ff225ba9ad71c4 Nuno Das Neves 2026-01-28 1135 goto put_partition;
ff225ba9ad71c4 Nuno Das Neves 2026-01-28 1136
621191d709b148 Nuno Das Neves 2025-03-14 1137 /*
621191d709b148 Nuno Das Neves 2025-03-14 1138 * Keep anon_inode_getfd last: it installs fd in the file struct and
621191d709b148 Nuno Das Neves 2025-03-14 1139 * thus makes the state accessible in user space.
621191d709b148 Nuno Das Neves 2025-03-14 1140 */
621191d709b148 Nuno Das Neves 2025-03-14 1141 ret = anon_inode_getfd("mshv_vp", &mshv_vp_fops, vp,
621191d709b148 Nuno Das Neves 2025-03-14 1142 O_RDWR | O_CLOEXEC);
621191d709b148 Nuno Das Neves 2025-03-14 1143 if (ret < 0)
ff225ba9ad71c4 Nuno Das Neves 2026-01-28 1144 goto remove_debugfs_vp;
621191d709b148 Nuno Das Neves 2025-03-14 1145
621191d709b148 Nuno Das Neves 2025-03-14 1146 /* already exclusive with the partition mutex for all ioctls */
621191d709b148 Nuno Das Neves 2025-03-14 1147 partition->pt_vp_count++;
621191d709b148 Nuno Das Neves 2025-03-14 1148 partition->pt_vp_array[args.vp_index] = vp;
621191d709b148 Nuno Das Neves 2025-03-14 1149
33c08ba966cf23 Stanislav Kinsburskii 2026-02-26 1150 goto out;
621191d709b148 Nuno Das Neves 2025-03-14 1151
ff225ba9ad71c4 Nuno Das Neves 2026-01-28 1152 remove_debugfs_vp:
ff225ba9ad71c4 Nuno Das Neves 2026-01-28 1153 mshv_debugfs_vp_remove(vp);
621191d709b148 Nuno Das Neves 2025-03-14 1154 put_partition:
621191d709b148 Nuno Das Neves 2025-03-14 1155 mshv_partition_put(partition);
621191d709b148 Nuno Das Neves 2025-03-14 1156 free_vp:
621191d709b148 Nuno Das Neves 2025-03-14 @1157 kfree(vp);
^^
freed.
621191d709b148 Nuno Das Neves 2025-03-14 1158 unmap_stats_pages:
d62313bdf5961b Jinank Jain 2025-10-10 1159 mshv_vp_stats_unmap(partition->pt_id, args.vp_index, stats_pages);
621191d709b148 Nuno Das Neves 2025-03-14 1160 unmap_ghcb_page:
19c515c27cee3b Jinank Jain 2025-10-10 1161 if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available())
19c515c27cee3b Jinank Jain 2025-10-10 1162 hv_unmap_vp_state_page(partition->pt_id, args.vp_index,
19c515c27cee3b Jinank Jain 2025-10-10 1163 HV_VP_STATE_PAGE_GHCB, ghcb_page,
621191d709b148 Nuno Das Neves 2025-03-14 1164 input_vtl_normal);
621191d709b148 Nuno Das Neves 2025-03-14 1165 unmap_register_page:
19c515c27cee3b Jinank Jain 2025-10-10 1166 if (!mshv_partition_encrypted(partition))
19c515c27cee3b Jinank Jain 2025-10-10 1167 hv_unmap_vp_state_page(partition->pt_id, args.vp_index,
621191d709b148 Nuno Das Neves 2025-03-14 1168 HV_VP_STATE_PAGE_REGISTERS,
19c515c27cee3b Jinank Jain 2025-10-10 1169 register_page, input_vtl_zero);
621191d709b148 Nuno Das Neves 2025-03-14 1170 unmap_intercept_message_page:
19c515c27cee3b Jinank Jain 2025-10-10 1171 hv_unmap_vp_state_page(partition->pt_id, args.vp_index,
621191d709b148 Nuno Das Neves 2025-03-14 1172 HV_VP_STATE_PAGE_INTERCEPT_MESSAGE,
19c515c27cee3b Jinank Jain 2025-10-10 1173 intercept_msg_page, input_vtl_zero);
621191d709b148 Nuno Das Neves 2025-03-14 1174 destroy_vp:
621191d709b148 Nuno Das Neves 2025-03-14 1175 hv_call_delete_vp(partition->pt_id, args.vp_index);
33c08ba966cf23 Stanislav Kinsburskii 2026-02-26 1176 out:
33c08ba966cf23 Stanislav Kinsburskii 2026-02-26 @1177 trace_mshv_create_vp(partition->pt_id, vp->vp_index, ret);
^^^^^^^^^^^^
vp dereferenced.
621191d709b148 Nuno Das Neves 2025-03-14 1178 return ret;
621191d709b148 Nuno Das Neves 2025-03-14 1179 }
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH, net-next] net: mana: Trigger VF reset/recovery on health check failure due to HWC timeout
From: Dipayaan Roy @ 2026-02-27 8:10 UTC (permalink / raw)
To: Long Li
Cc: KY Srinivasan, Haiyang Zhang, wei.liu@kernel.org, Dexuan Cui,
andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com, Konstantin Taranov,
horms@kernel.org, shradhagupta@linux.microsoft.com,
ssengar@linux.microsoft.com, ernis@linux.microsoft.com,
Shiraz Saleem, linux-hyperv@vger.kernel.org,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-rdma@vger.kernel.org, Dipayaan Roy
In-Reply-To: <DS3PR21MB5735F00E300CB4B7E54DA710CE72A@DS3PR21MB5735.namprd21.prod.outlook.com>
On Thu, Feb 26, 2026 at 07:48:31PM +0000, Long Li wrote:
> > The GF stats periodic query is used as mechanism to monitor HWC health check.
> > If this HWC command times out, it is a strong indication that the device/SoC is in a
> > faulty state and requires recovery.
> >
> > Today, when a timeout is detected, the driver marks hwc_timeout_occurred,
> > clears cached stats, and stops rescheduling the periodic work. However, the
> > device itself is left in the same failing state.
> >
> > Extend the timeout handling path to trigger the existing MANA VF recovery
> > service by queueing a GDMA_EQE_HWC_RESET_REQUEST work item.
> > This is expected to initiate the appropriate recovery flow by suspende resume
> > first and if it fails then trigger a bus rescan.
> >
> > This change is intentionally limited to HWC command timeouts and does not
> > trigger recovery for errors reported by the SoC as a normal command response.
> >
> > Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
> > ---
> > .../net/ethernet/microsoft/mana/gdma_main.c | 14 +++-------
> > drivers/net/ethernet/microsoft/mana/mana_en.c | 28 ++++++++++++++++++-
> > include/net/mana/gdma.h | 16 +++++++++--
> > 3 files changed, 45 insertions(+), 13 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c
> > b/drivers/net/ethernet/microsoft/mana/gdma_main.c
> > index 0055c231acf6..16c438d2aaa3 100644
> > --- a/drivers/net/ethernet/microsoft/mana/gdma_main.c
> > +++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c
> > @@ -490,15 +490,9 @@ static void mana_serv_reset(struct pci_dev *pdev)
> > dev_info(&pdev->dev, "MANA reset cycle completed\n");
> >
> > out:
> > - gc->in_service = false;
> > + clear_bit(GC_IN_SERVICE, &gc->flags);
> > }
> >
> > -struct mana_serv_work {
> > - struct work_struct serv_work;
> > - struct pci_dev *pdev;
> > - enum gdma_eqe_type type;
> > -};
> > -
> > static void mana_do_service(enum gdma_eqe_type type, struct pci_dev *pdev)
> > {
> > switch (type) {
> > @@ -542,7 +536,7 @@ static void mana_recovery_delayed_func(struct
> > work_struct *w)
> > spin_unlock_irqrestore(&work->lock, flags); }
> >
> > -static void mana_serv_func(struct work_struct *w)
> > +void mana_serv_func(struct work_struct *w)
> > {
> > struct mana_serv_work *mns_wk;
> > struct pci_dev *pdev;
> > @@ -624,7 +618,7 @@ static void mana_gd_process_eqe(struct gdma_queue
> > *eq)
> > break;
> > }
> >
> > - if (gc->in_service) {
> > + if (test_bit(GC_IN_SERVICE, &gc->flags)) {
> > dev_info(gc->dev, "Already in service\n");
> > break;
> > }
> > @@ -641,7 +635,7 @@ static void mana_gd_process_eqe(struct gdma_queue
> > *eq)
> > }
> >
> > dev_info(gc->dev, "Start MANA service type:%d\n", type);
> > - gc->in_service = true;
> > + set_bit(GC_IN_SERVICE, &gc->flags);
> > mns_wk->pdev = to_pci_dev(gc->dev);
> > mns_wk->type = type;
> > pci_dev_get(mns_wk->pdev);
> > diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c
> > b/drivers/net/ethernet/microsoft/mana/mana_en.c
> > index 91c418097284..8da574cf06f2 100644
> > --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
> > +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
> > @@ -879,7 +879,7 @@ static void mana_tx_timeout(struct net_device *netdev,
> > unsigned int txqueue)
> > struct gdma_context *gc = ac->gdma_dev->gdma_context;
> >
> > /* Already in service, hence tx queue reset is not required.*/
> > - if (gc->in_service)
> > + if (test_bit(GC_IN_SERVICE, &gc->flags))
> > return;
> >
> > /* Note: If there are pending queue reset work for this port(apc), @@ -
> > 3533,6 +3533,8 @@ static void mana_gf_stats_work_handler(struct work_struct
> > *work) {
> > struct mana_context *ac =
> > container_of(to_delayed_work(work), struct mana_context,
> > gf_stats_work);
> > + struct gdma_context *gc = ac->gdma_dev->gdma_context;
> > + struct mana_serv_work *mns_wk;
> > int err;
> >
> > err = mana_query_gf_stats(ac);
> > @@ -3540,6 +3542,30 @@ static void mana_gf_stats_work_handler(struct
> > work_struct *work)
> > /* HWC timeout detected - reset stats and stop rescheduling */
> > ac->hwc_timeout_occurred = true;
> > memset(&ac->hc_stats, 0, sizeof(ac->hc_stats));
> > + dev_warn(gc->dev,
> > + "Gf stats wk handler: gf stats query timed out.\n");
> > +
> > + /* As HWC timed out, indicating a faulty HW state and needs a
> > + * reset.
> > + */
> > + if (!test_and_set_bit(GC_IN_SERVICE, &gc->flags)) {
> > + if (!try_module_get(THIS_MODULE)) {
> > + dev_info(gc->dev, "Module is unloading\n");
> > + return;
> > + }
> > +
> > + mns_wk = kzalloc(sizeof(*mns_wk), GFP_ATOMIC);
> > + if (!mns_wk) {
> > + module_put(THIS_MODULE);
>
> Maybe it's not necessary: check if you want to call clear_bit(GC_IN_SERVICE, &gc->flags) here?
>
yes it makes sense to clear it here.
> > + return;
> > + }
> > +
> > + mns_wk->pdev = to_pci_dev(gc->dev);
> > + mns_wk->type = GDMA_EQE_HWC_RESET_REQUEST;
> > + pci_dev_get(mns_wk->pdev);
> > + INIT_WORK(&mns_wk->serv_work, mana_serv_func);
> > + schedule_work(&mns_wk->serv_work);
> > + }
> > return;
> > }
> > schedule_delayed_work(&ac->gf_stats_work,
> > MANA_GF_STATS_PERIOD); diff --git a/include/net/mana/gdma.h
>
Regards
^ 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