6.6.120-rc1 review
Subsystems (6)
Greg Kroah-Hartman
maintainerPATCH 693/737 media: verisilicon: Fix CPU stalls on G2 bus error
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolas Dufresne <[email protected]>
[ Upstream commit 19c286b755072a22a063052f530a6b1fac8a1f63 ]
In some seek stress tests, we are getting IRQ from the G2 decoder where the dec_bus_int and the dec_e bits are high, meaning the decoder is still running despite the error.
Fix this by reworking the IRQ handler to only finish the job once we have reached completion and move the software reset to when our software watchdog triggers.
This way, we let the hardware continue on errors when it did not self reset and in worse case scenario the hardware timeout will automatically stop it. The actual error will be fixed in a follow up patch.
--- drivers/media/platform/verisilicon/hantro_g2.c | 84 ++++++++++++---- drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c | 2 drivers/media/platform/verisilicon/hantro_g2_regs.h | 13 ++ drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c | 2 drivers/media/platform/verisilicon/hantro_hw.h | 1 drivers/media/platform/verisilicon/imx8m_vpu_hw.c | 2 6 files changed, 83 insertions(+), 21 deletions(-)
drivers/media/platform/verisilicon/hantro_g2.c +67 -17
@@ -5,43 +5,93 @@* Copyright (C) 2021 Collabora Ltd, Andrzej Pietrasiewicz <[email protected]> */ +#include <linux/delay.h> #include "hantro_hw.h" #include "hantro_g2_regs.h" #define G2_ALIGN 16 -void hantro_g2_check_idle (struct hantro_dev *vpu) +static bool hantro_g2_active (struct hantro_ctx *ctx) { -int i; +struct hantro_dev *vpu = ctx->dev; +u32 status; + + status =vdpu_read (vpu,G2_REG_INTERRUPT ); + +return (status &G2_REG_INTERRUPT_DEC_E ); +} -for (i =0 ; i <3 ; i++) { -u32 status; +/** +* hantro_g2_reset: +* @ctx: the hantro context +* +* Emulates a reset using Hantro abort function. Failing this procedure would +* results in programming a running IP which leads to CPU hang. +* +* Using a hard reset procedure instead is prefferred. +*/ +void hantro_g2_reset (struct hantro_ctx *ctx) +{ +struct hantro_dev *vpu = ctx->dev; +u32 status; -/* Make sure the VPU is idle */ - status =vdpu_read (vpu,G2_REG_INTERRUPT ); -if (status &G2_REG_INTERRUPT_DEC_E ) { -dev_warn (vpu->dev,"device still running, aborting" ); - status |=G2_REG_INTERRUPT_DEC_ABORT_E |G2_REG_INTERRUPT_DEC_IRQ_DIS ; -vdpu_write (vpu, status,G2_REG_INTERRUPT ); - } + status =vdpu_read (vpu,G2_REG_INTERRUPT ); +if (status &G2_REG_INTERRUPT_DEC_E ) { +dev_warn_ratelimited (vpu->dev,"device still running, aborting" ); + status |=G2_REG_INTERRUPT_DEC_ABORT_E |G2_REG_INTERRUPT_DEC_IRQ_DIS ; +vdpu_write (vpu, status,G2_REG_INTERRUPT ); + +do { +mdelay (1 ); + }while (hantro_g2_active (ctx)); } }irqreturn_t hantro_g2_irq (int irq,void *dev_id) {struct hantro_dev *vpu = dev_id; -enum vb2_buffer_state state;u32 status; status =vdpu_read (vpu,G2_REG_INTERRUPT ); - state = (status &G2_REG_INTERRUPT_DEC_RDY_INT ) ? -VB2_BUF_STATE_DONE :VB2_BUF_STATE_ERROR ; -vdpu_write (vpu,0 ,G2_REG_INTERRUPT ); -vdpu_write (vpu,G2_REG_CONFIG_DEC_CLK_GATE_E ,G2_REG_CONFIG ); +if (!(status &G2_REG_INTERRUPT_DEC_IRQ )) +return IRQ_NONE ; + +hantro_reg_write (vpu, &g2_dec_irq,0 ); +hantro_reg_write (vpu, &g2_dec_int_stat,0 ); +hantro_reg_write (vpu, &g2_clk_gate_e,1 ); + +if (status &G2_REG_INTERRUPT_DEC_RDY_INT ) { +hantro_irq_done (vpu,VB2_BUF_STATE_DONE ); +return IRQ_HANDLED ; + } + +if (status &G2_REG_INTERRUPT_DEC_ABORT_INT ) { +/* disabled on abort, though lets be safe and handle it */ +dev_warn_ratelimited (vpu->dev,"decode operation aborted." ); +return IRQ_HANDLED ; + } + +if (status &G2_REG_INTERRUPT_DEC_LAST_SLICE_INT ) +dev_warn_ratelimited (vpu->dev,"not all macroblocks were decoded." ); + +if (status &G2_REG_INTERRUPT_DEC_BUS_INT ) +dev_warn_ratelimited (vpu->dev,"bus error detected." ); + +if (status &G2_REG_INTERRUPT_DEC_ERROR_INT ) +dev_warn_ratelimited (vpu->dev,"decode error detected." ); -hantro_irq_done (vpu, state); +if (status &G2_REG_INTERRUPT_DEC_TIMEOUT ) +dev_warn_ratelimited (vpu->dev,"frame decode timed out." ); + +/** +* If the decoding haven't stopped, let it continue. The hardware timeout +* will trigger if it is trully stuck. +*/ +if (status &G2_REG_INTERRUPT_DEC_E ) +return IRQ_HANDLED ; +hantro_irq_done (vpu,VB2_BUF_STATE_ERROR );return IRQ_HANDLED ; }
drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c +0 -2
@@ -578,8 +578,6 @@ int hantro_g2_hevc_dec_run(struct hantrostruct hantro_dev *vpu = ctx->dev;int ret; -hantro_g2_check_idle (vpu); -/* Prepare HEVC decoder context. */ ret =hantro_hevc_dec_prepare_run (ctx);if (ret)
drivers/media/platform/verisilicon/hantro_g2_regs.h +13 -0
@@ -22,7 +22,14 @@#define G2_REG_VERSION G2_SWREG(0)#define G2_REG_INTERRUPT G2_SWREG(1) +#define G2_REG_INTERRUPT_DEC_LAST_SLICE_INT BIT(19) +#define G2_REG_INTERRUPT_DEC_TIMEOUT BIT(18) +#define G2_REG_INTERRUPT_DEC_ERROR_INT BIT(16) +#define G2_REG_INTERRUPT_DEC_BUF_INT BIT(14) +#define G2_REG_INTERRUPT_DEC_BUS_INT BIT(13)#define G2_REG_INTERRUPT_DEC_RDY_INT BIT(12) +#define G2_REG_INTERRUPT_DEC_ABORT_INT BIT(11) +#define G2_REG_INTERRUPT_DEC_IRQ BIT(8)#define G2_REG_INTERRUPT_DEC_ABORT_E BIT(5)#define G2_REG_INTERRUPT_DEC_IRQ_DIS BIT(4)#define G2_REG_INTERRUPT_DEC_E BIT(0)
@@ -35,6 +42,9 @@#define BUS_WIDTH_128 2#define BUS_WIDTH_256 3 +#define g2_dec_int_stat G2_DEC_REG(1, 11, 0xf) +#define g2_dec_irq G2_DEC_REG(1, 8, 0x1) +#define g2_strm_swap G2_DEC_REG(2, 28, 0xf)#define g2_strm_swap_old G2_DEC_REG(2, 27, 0x1f)#define g2_pic_swap G2_DEC_REG(2, 22, 0x1f)
@@ -225,6 +235,9 @@#define vp9_filt_level_seg5 G2_DEC_REG(19, 8, 0x3f)#define vp9_quant_seg5 G2_DEC_REG(19, 0, 0xff) +#define g2_timemout_override_e G2_DEC_REG(45, 31, 0x1) +#define g2_timemout_cycles G2_DEC_REG(45, 0, 0x7fffffff) +#define hevc_cur_poc_00 G2_DEC_REG(46, 24, 0xff)#define hevc_cur_poc_01 G2_DEC_REG(46, 16, 0xff)#define hevc_cur_poc_02 G2_DEC_REG(46, 8, 0xff)
drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c +0 -2
@@ -893,8 +893,6 @@ int hantro_g2_vp9_dec_run(struct hantro_struct vb2_v4l2_buffer *dst;int ret; -hantro_g2_check_idle (ctx->dev); - ret =start_prepare_run (ctx, &decode_params);if (ret) {hantro_end_prepare_run (ctx);
drivers/media/platform/verisilicon/hantro_hw.h +1 -0
@@ -541,6 +541,7 @@ void hantro_g2_vp9_dec_done(struct hantrint hantro_vp9_dec_init (struct hantro_ctx *ctx);void hantro_vp9_dec_exit (struct hantro_ctx *ctx);void hantro_g2_check_idle (struct hantro_dev *vpu); +void hantro_g2_reset (struct hantro_ctx *ctx);irqreturn_t hantro_g2_irq (int irq,void *dev_id);#endif /* HANTRO_HW_H_ */
drivers/media/platform/verisilicon/imx8m_vpu_hw.c +2 -0
@@ -312,11 +312,13 @@ static const struct hantro_codec_ops imxstatic const struct hantro_codec_ops imx8mq_vpu_g2_codec_ops[] = { [HANTRO_MODE_HEVC_DEC ] = { .run = hantro_g2_hevc_dec_run, + .reset = hantro_g2_reset, .init = hantro_hevc_dec_init, .exit = hantro_hevc_dec_exit, }, [HANTRO_MODE_VP9_DEC ] = { .run = hantro_g2_vp9_dec_run, + .reset = hantro_g2_reset, .done = hantro_g2_vp9_dec_done, .init = hantro_vp9_dec_init, .exit = hantro_vp9_dec_exit,
Greg Kroah-Hartman
maintainerPATCH 694/737 mm/balloon_compaction: we cannot have isolated pages in the balloon list
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand <[email protected]>
[ Upstream commit fb05f992b6bbb4702307d96f00703ee637b24dbf ]
Patch series "mm/migration: rework movable_ops page migration (part 1)", v2.
In the future, as we decouple "struct page" from "struct folio", pages that support "non-lru page migration" -- movable_ops page migration such as memory balloons and zsmalloc -- will no longer be folios. They will not have ->mapping, ->lru, and likely no refcount and no page lock. But they will have a type and flags 🙂
This is the first part (other parts not written yet) of decoupling movable_ops page migration from folio migration.
In this series, we get rid of the ->mapping usage, and start cleaning up the code + separating it from folio migration.
Migration core will have to be further reworked to not treat movable_ops pages like folios. This is the first step into that direction.
This patch (of 29):
The core will set PG_isolated only after mops->isolate_page() was called. In case of the balloon, that is where we will remove it from the balloon list. So we cannot have isolated pages in the balloon list.
Let's drop this unnecessary check.
Stable-dep-of: 0da2ba35c0d5 ("powerpc/pseries/cmm: adjust BALLOON_MIGRATE when migrating pages")
--- mm/balloon_compaction.c | 6 ------ 1 file changed, 6 deletions(-)
mm/balloon_compaction.c +0 -6
@@ -93,12 +93,6 @@ size_t balloon_page_list_dequeue(structif (!trylock_page (page))continue ; -if (IS_ENABLED (CONFIG_BALLOON_COMPACTION ) && -PageIsolated (page)) { -/* raced with isolation */ -unlock_page (page); -continue ; - }balloon_page_delete (page);__count_vm_event (BALLOON_DEFLATE );list_add (&page->lru, pages);
Greg Kroah-Hartman
maintainerPATCH 695/737 mm/balloon_compaction: convert balloon_page_delete() to balloon_page_finalize()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand <[email protected]>
[ Upstream commit 15504b1163007bbfbd9a63460d5c14737c16e96d ]
Let's move the removal of the page from the balloon list into the single caller, to remove the dependency on the PG_isolated flag and clarify locking requirements.
Note that for now, balloon_page_delete() was used on two paths:
(1) Removing a page from the balloon for deflation through balloon_page_list_dequeue()
(2) Removing an isolated page from the balloon for migration in the per-driver migration handlers. Isolated pages were already removed from the balloon list during isolation.
So instead of relying on the flag, we can just distinguish both cases directly and handle it accordingly in the caller.
We'll shuffle the operations a bit such that they logically make more sense (e.g., remove from the list before clearing flags).
In balloon migration functions we can now move the balloon_page_finalize() out of the balloon lock and perform the finalization just before dropping the balloon reference.
Document that the page lock is currently required when modifying the movability aspects of a page; hopefully we can soon decouple this from the page lock.
Stable-dep-of: 0da2ba35c0d5 ("powerpc/pseries/cmm: adjust BALLOON_MIGRATE when migrating pages")
--- arch/powerpc/platforms/pseries/cmm.c | 2 - drivers/misc/vmw_balloon.c | 3 -- drivers/virtio/virtio_balloon.c | 4 --- include/linux/balloon_compaction.h | 43 +++++++++++++---------------------- mm/balloon_compaction.c | 3 +- 5 files changed, 21 insertions(+), 34 deletions(-)
arch/powerpc/platforms/pseries/cmm.c +1 -1
@@ -532,7 +532,6 @@ static int cmm_migratepage(struct balloospin_lock_irqsave (&b_dev_info->pages_lock, flags);balloon_page_insert (b_dev_info, newpage); -balloon_page_delete (page); b_dev_info->isolated_pages--;spin_unlock_irqrestore (&b_dev_info->pages_lock, flags);
@@ -542,6 +541,7 @@ static int cmm_migratepage(struct balloo*/ plpar_page_set_active (page); +balloon_page_finalize (page);/* balloon page list reference */ put_page (page);
drivers/misc/vmw_balloon.c +1 -2
@@ -1789,8 +1789,7 @@ static int vmballoon_migratepage(struct* @pages_lock . We keep holding @comm_lock since we will need it in a * second. */ -balloon_page_delete (page); - +balloon_page_finalize (page);put_page (page);/* Inflate */
drivers/virtio/virtio_balloon.c +1 -3
@@ -789,15 +789,13 @@ static int virtballoon_migratepage(structell_host (vb, vb->inflate_vq);/* balloon's page migration 2nd step -- deflate "page" */ -spin_lock_irqsave (&vb_dev_info->pages_lock, flags); -balloon_page_delete (page); -spin_unlock_irqrestore (&vb_dev_info->pages_lock, flags); vb->num_pfns =VIRTIO_BALLOON_PAGES_PER_PAGE ;set_page_pfns (vb, vb->pfns, page);tell_host (vb, vb->deflate_vq);mutex_unlock (&vb->balloon_lock); +balloon_page_finalize (page);put_page (page);/* balloon reference */ return MIGRATEPAGE_SUCCESS ;
include/linux/balloon_compaction.h +16 -27
61 lines not on this page · raw message
mm/balloon_compaction.c +2 -1
@@ -93,7 +93,8 @@ size_t balloon_page_list_dequeue(structif (!trylock_page (page))continue ; -balloon_page_delete (page); +list_del (&page->lru); +balloon_page_finalize (page);__count_vm_event (BALLOON_DEFLATE );list_add (&page->lru, pages);unlock_page (page);
Greg Kroah-Hartman
maintainerPATCH 696/737 powerpc/pseries/cmm: adjust BALLOON_MIGRATE when migrating pages
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand <[email protected]>
[ Upstream commit 0da2ba35c0d532ca0fe7af698b17d74c4d084b9a ]
Let's properly adjust BALLOON_MIGRATE like the other drivers.
Note that the INFLATE/DEFLATE events are triggered from the core when enqueueing/dequeueing pages.
This was found by code inspection.
--- arch/powerpc/platforms/pseries/cmm.c | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/platforms/pseries/cmm.c +1 -0
@@ -532,6 +532,7 @@ static int cmm_migratepage(struct balloospin_lock_irqsave (&b_dev_info->pages_lock, flags);balloon_page_insert (b_dev_info, newpage); +__count_vm_event (BALLOON_MIGRATE ); b_dev_info->isolated_pages--;spin_unlock_irqrestore (&b_dev_info->pages_lock, flags);
Greg Kroah-Hartman
maintainerPATCH 697/737 KVM: nVMX: Immediately refresh APICv controls as needed on nested VM-Exit
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dongli Zhang <[email protected]>
[ Upstream commit 29763138830916f46daaa50e83e7f4f907a3236b ]
If an APICv status updated was pended while L2 was active, immediately refresh vmcs01's controls instead of pending KVM_REQ_APICV_UPDATE as kvm_vcpu_update_apicv() only calls into vendor code if a change is necessary.
E.g. if APICv is inhibited, and then activated while L2 is running:
kvm_vcpu_update_apicv()
|
-> __kvm_vcpu_update_apicv()
|
-> apic->apicv_active = true
|
-> vmx_refresh_apicv_exec_ctrl()
|
-> vmx->nested.update_vmcs01_apicv_status = true
|
-> returnThen L2 exits to L1:
__nested_vmx_vmexit()
|
-> kvm_make_request(KVM_REQ_APICV_UPDATE)
vcpu_enter_guest(): KVM_REQ_APICV_UPDATE
-> kvm_vcpu_update_apicv()
|
-> __kvm_vcpu_update_apicv()
|
-> return // because if (apic->apicv_active == activate)--- arch/x86/kvm/vmx/nested.c | 2 +- arch/x86/kvm/vmx/vmx.c | 2 +- arch/x86/kvm/vmx/vmx.h | 1 + 3 files changed, 3 insertions(+), 2 deletions(-)
arch/x86/kvm/vmx/nested.c +1 -1
@@ -4908,7 +4908,7 @@ void nested_vmx_vmexit(struct kvm_vcpu *if (vmx->nested.update_vmcs01_apicv_status) { vmx->nested.update_vmcs01_apicv_status = false; -kvm_make_request (KVM_REQ_APICV_UPDATE , vcpu); +vmx_refresh_apicv_exec_ctrl (vcpu); }if (vmx->nested.update_vmcs01_hwapic_isr) {
arch/x86/kvm/vmx/vmx.c +1 -1
@@ -4451,7 +4451,7 @@ static u32 vmx_vmexit_ctrl(void) ~(VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |VM_EXIT_LOAD_IA32_EFER ); } -static void vmx_refresh_apicv_exec_ctrl (struct kvm_vcpu *vcpu) +void vmx_refresh_apicv_exec_ctrl (struct kvm_vcpu *vcpu) {struct vcpu_vmx *vmx =to_vmx (vcpu);
arch/x86/kvm/vmx/vmx.h +1 -0
@@ -395,6 +395,7 @@ void __vmx_set_segment(struct kvm_vcpu *u64 construct_eptp (struct kvm_vcpu *vcpu,hpa_t root_hpa,int root_level);bool vmx_guest_inject_ac (struct kvm_vcpu *vcpu); +void vmx_refresh_apicv_exec_ctrl (struct kvm_vcpu *vcpu);void vmx_update_exception_bitmap (struct kvm_vcpu *vcpu);bool vmx_nmi_blocked (struct kvm_vcpu *vcpu);bool __vmx_interrupt_blocked (struct kvm_vcpu *vcpu);
Greg Kroah-Hartman
maintainerPATCH 698/737 media: amphion: Add a frame flush mode for decoder
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Qian <[email protected]>
[ Upstream commit 9ea16ba6eaf93f25f61855751f71e2e701709ddf ]
By default the amphion decoder will pre-parse 3 frames before starting to decode the first frame. Alternatively, a block of flush padding data can be appended to the frame, which will ensure that the decoder can start decoding immediately after parsing the flush padding data, thus potentially reducing decoding latency.
This mode was previously only enabled, when the display delay was set to
0. Allow the user to manually toggle the use of that mode via a module parameter called low_latency, which enables the mode without changing the display order.
Stable-dep-of: 634c2cd17bd0 ("media: amphion: Remove vpu_vb_is_codecconfig")
--- drivers/media/platform/amphion/vpu_malone.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
drivers/media/platform/amphion/vpu_malone.c +13 -1
@@ -25,6 +25,10 @@#include "vpu_imx8q.h" #include "vpu_malone.h" +static bool low_latency; +module_param (low_latency, bool,0644 ); +MODULE_PARM_DESC (low_latency,"Set low latency frame flush mode: 0 (disable) or 1 (enable)" ); +#define CMD_SIZE 25600#define MSG_SIZE 25600#define CODEC_SIZE 0x1000
@@ -1567,7 +1571,15 @@ static int vpu_malone_input_frame_data(svpu_malone_update_wptr (str_buf, wptr); -if (disp_imm && !vpu_vb_is_codecconfig (vbuf)) { +/* +* Enable the low latency flush mode if display delay is set to 0 +* or the low latency frame flush mode if it is set to 1. +* The low latency flush mode requires some padding data to be appended to each frame, +* but there must not be any padding data between the sequence header and the frame. +* This module is currently only supported for the H264 and HEVC formats, +* for other formats, vpu_malone_add_scode() will return 0. +*/ +if ((disp_imm || low_latency) && !vpu_vb_is_codecconfig (vbuf)) { ret = vpu_malone_add_scode(inst->core->iface, inst->id, &inst->stream_buffer,
Greg Kroah-Hartman
maintainerPATCH 699/737 media: amphion: Make some vpu_v4l2 functions static
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laurent Pinchart <[email protected]>
[ Upstream commit 5d1e54bb4dc6741284a3ed587e994308ddee2f16 ]
Some functions defined in vpu_v4l2.c are never used outside of that compilation unit. Make them static.
Stable-dep-of: 634c2cd17bd0 ("media: amphion: Remove vpu_vb_is_codecconfig")
--- drivers/media/platform/amphion/vpu_v4l2.c | 12 +++++++++--- drivers/media/platform/amphion/vpu_v4l2.h | 8 -------- 2 files changed, 9 insertions(+), 11 deletions(-)
drivers/media/platform/amphion/vpu_v4l2.c +9 -3
@@ -24,6 +24,11 @@#include "vpu_msgs.h" #include "vpu_helpers.h" +static char *vpu_type_name (u32 type) +{ +return V4L2_TYPE_IS_OUTPUT (type) ?"output" :"capture" ; +} +void vpu_inst_lock (struct vpu_inst *inst) {mutex_lock (&inst->lock);
@@ -42,7 +47,7 @@ dma_addr_t vpu_get_vb_phy_addr(struct vb vb->planes[plane_no].data_offset; } -unsigned int vpu_get_vb_length (struct vb2_buffer *vb,u32 plane_no) +static unsigned int vpu_get_vb_length (struct vb2_buffer *vb,u32 plane_no) {if (plane_no >= vb->num_planes)return 0 ;
@@ -74,7 +79,7 @@ void vpu_v4l2_set_error(struct vpu_instvpu_inst_unlock (inst); } -int vpu_notify_eos (struct vpu_inst *inst) +static int vpu_notify_eos (struct vpu_inst *inst) {static const struct v4l2_event ev = { .id =0 ,
@@ -546,7 +551,8 @@ static void vpu_vb2_buf_finish(struct vbcall_void_vop (inst, on_queue_empty, q->type); } -void vpu_vb2_buffers_return (struct vpu_inst *inst,unsigned int type,enum vb2_buffer_state state) +static void vpu_vb2_buffers_return (struct vpu_inst *inst,unsigned int type, +enum vb2_buffer_state state) {struct vb2_v4l2_buffer *buf;
drivers/media/platform/amphion/vpu_v4l2.h +0 -8
@@ -25,15 +25,12 @@ void vpu_skip_frame(struct vpu_inst *insstruct vb2_v4l2_buffer *vpu_find_buf_by_sequence (struct vpu_inst *inst,u32 type,u32 sequence);struct vb2_v4l2_buffer *vpu_find_buf_by_idx (struct vpu_inst *inst,u32 type,u32 idx);void vpu_v4l2_set_error (struct vpu_inst *inst); -int vpu_notify_eos (struct vpu_inst *inst);int vpu_notify_source_change (struct vpu_inst *inst);int vpu_set_last_buffer_dequeued (struct vpu_inst *inst,bool eos); -void vpu_vb2_buffers_return (struct vpu_inst *inst,unsigned int type,enum vb2_buffer_state state);int vpu_get_num_buffers (struct vpu_inst *inst,u32 type);bool vpu_is_source_empty (struct vpu_inst *inst);dma_addr_t vpu_get_vb_phy_addr (struct vb2_buffer *vb,u32 plane_no); -unsigned int vpu_get_vb_length (struct vb2_buffer *vb,u32 plane_no);static inline struct vpu_format *vpu_get_format (struct vpu_inst *inst,u32 type) {if (V4L2_TYPE_IS_OUTPUT (type))
@@ -42,11 +39,6 @@ static inline struct vpu_format *vpu_getreturn &inst->cap_format; } -static inline char *vpu_type_name (u32 type) -{ -return V4L2_TYPE_IS_OUTPUT (type) ?"output" :"capture" ; -} -static inline int vpu_vb_is_codecconfig (struct vb2_v4l2_buffer *vbuf) {#ifdef V4L2_BUF_FLAG_CODECCONFIG
Greg Kroah-Hartman
maintainerPATCH 700/737 media: amphion: Remove vpu_vb_is_codecconfig
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Qian <[email protected]>
[ Upstream commit 634c2cd17bd021487c57b95973bddb14be8002ff ]
Currently the function vpu_vb_is_codecconfig() always returns 0. Delete it and its related code.
--- drivers/media/platform/amphion/vpu_malone.c | 23 +++-------------------- drivers/media/platform/amphion/vpu_v4l2.c | 10 ---------- drivers/media/platform/amphion/vpu_v4l2.h | 10 ---------- 3 files changed, 3 insertions(+), 40 deletions(-)
drivers/media/platform/amphion/vpu_malone.c +3 -20
@@ -1320,22 +1320,18 @@ static int vpu_malone_insert_scode_vc1_g {if (!scode->inst->total_input_count)return 0 ; -if (vpu_vb_is_codecconfig (to_vb2_v4l2_buffer (scode->vb))) - scode->need_data =0 ;return 0 ; }static int vpu_malone_insert_scode_vc1_g_pic (struct malone_scode_t *scode) { -struct vb2_v4l2_buffer *vbuf;u8 nal_hdr[MALONE_VC1_NAL_HEADER_LEN ];u32 *data =NULL ;int ret; - vbuf =to_vb2_v4l2_buffer (scode->vb); data =vb2_plane_vaddr (scode->vb,0 ); -if (scode->inst->total_input_count ==0 ||vpu_vb_is_codecconfig (vbuf)) +if (scode->inst->total_input_count ==0 )return 0 ;if (MALONE_VC1_CONTAIN_NAL (*data))return 0 ;
@@ -1356,8 +1352,6 @@ static int vpu_malone_insert_scode_vc1_lint size =0 ;u8 rcv_seqhdr[MALONE_VC1_RCV_SEQ_HEADER_LEN ]; -if (vpu_vb_is_codecconfig (to_vb2_v4l2_buffer (scode->vb))) - scode->need_data =0 ;if (scode->inst->total_input_count)return 0 ; scode->need_data =0 ;
@@ -1543,7 +1537,7 @@ static int vpu_malone_input_frame_data(s scode.vb = vb; scode.wptr = wptr; scode.need_data =1 ; -if (vbuf->sequence ==0 ||vpu_vb_is_codecconfig (vbuf)) +if (vbuf->sequence ==0 ) ret =vpu_malone_insert_scode (&scode,SCODE_SEQUENCE );if (ret <0 )
@@ -1579,7 +1573,7 @@ static int vpu_malone_input_frame_data(s* This module is currently only supported for the H264 and HEVC formats, * for other formats, vpu_malone_add_scode() will return 0. */ -if ((disp_imm || low_latency) && !vpu_vb_is_codecconfig (vbuf)) { +if (disp_imm || low_latency) { ret = vpu_malone_add_scode(inst->core->iface, inst->id, &inst->stream_buffer,
@@ -1626,7 +1620,6 @@ int vpu_malone_input_frame(struct vpu_sh struct vpu_inst *inst, struct vb2_buffer *vb) { struct vpu_dec_ctrl *hc = shared->priv; -struct vb2_v4l2_buffer *vbuf;struct vpu_malone_str_buffer __iomem *str_buf = hc->str_buf[inst->id];u32 disp_imm = hc->codec_param[inst->id].disp_imm;u32 size;
@@ -1640,16 +1633,6 @@ int vpu_malone_input_frame(struct vpu_shreturn ret; size = ret; -/* -* if buffer only contain codec data, and the timestamp is invalid, -* don't put the invalid timestamp to resync -* merge the data to next frame -*/ - vbuf =to_vb2_v4l2_buffer (vb); -if (vpu_vb_is_codecconfig (vbuf)) { - inst->extra_size += size; -return 0 ; - }if (inst->extra_size) { size += inst->extra_size; inst->extra_size =0 ;
drivers/media/platform/amphion/vpu_v4l2.c +0 -10
@@ -342,16 +342,6 @@ struct vb2_v4l2_buffer *vpu_next_src_bufif (!src_buf ||vpu_get_buffer_state (src_buf) ==VPU_BUF_STATE_IDLE )return NULL ; -while (vpu_vb_is_codecconfig (src_buf)) { -v4l2_m2m_src_buf_remove (inst->fh.m2m_ctx); -vpu_set_buffer_state (src_buf,VPU_BUF_STATE_IDLE ); -v4l2_m2m_buf_done (src_buf,VB2_BUF_STATE_DONE ); - - src_buf =v4l2_m2m_next_src_buf (inst->fh.m2m_ctx); -if (!src_buf ||vpu_get_buffer_state (src_buf) ==VPU_BUF_STATE_IDLE ) -return NULL ; - } -return src_buf; }
drivers/media/platform/amphion/vpu_v4l2.h +0 -10
@@ -38,14 +38,4 @@ static inline struct vpu_format *vpu_get else return &inst->cap_format; } - -static inline int vpu_vb_is_codecconfig (struct vb2_v4l2_buffer *vbuf) -{ -#ifdef V4L2_BUF_FLAG_CODECCONFIG -return (vbuf->flags &V4L2_BUF_FLAG_CODECCONFIG ) ?1 :0 ; -#else -return 0 ; -#endif -} -#endif
Greg Kroah-Hartman
maintainerPATCH 701/737 media: mediatek: vcodec: Use spinlock for context list protection lock
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen-Yu Tsai <[email protected]>
[ Upstream commit a5844227e0f030d2af2d85d4aed10c5eca6ca176 ]
Previously a mutex was added to protect the encoder and decoder context lists from unexpected changes originating from the SCP IP block, causing the context pointer to go invalid, resulting in a NULL pointer dereference in the IPI handler.
Turns out on the MT8173, the VPU IPI handler is called from hard IRQ context. This causes a big warning from the scheduler. This was first reported downstream on the ChromeOS kernels, but is also reproducible on mainline using Fluster with the FFmpeg v4l2m2m decoders. Even though the actual capture format is not supported, the affected code paths are triggered.
Since this lock just protects the context list and operations on it are very fast, it should be OK to switch to a spinlock.
--- drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c | 10 +++++--- drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c | 12 +++++----- drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h | 2 - drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c | 5 ++-- drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c | 12 +++++----- drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h | 2 - drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c | 5 ++-- 7 files changed, 28 insertions(+), 20 deletions(-)
drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c +6 -4
@@ -47,30 +47,32 @@ static void mtk_vcodec_vpu_reset_dec_han {struct mtk_vcodec_dec_dev *dev = priv;struct mtk_vcodec_dec_ctx *ctx; +unsigned long flags;dev_err (&dev->plat_dev->dev,"Watchdog timeout!!" ); -mutex_lock (&dev->dev_ctx_lock); +spin_lock_irqsave (&dev->dev_ctx_lock, flags);list_for_each_entry (ctx, &dev->ctx_list, list) { ctx->state =MTK_STATE_ABORT ;mtk_v4l2_vdec_dbg (0 , ctx,"[%d] Change to state MTK_STATE_ABORT" , ctx->id); } -mutex_unlock (&dev->dev_ctx_lock); +spin_unlock_irqrestore (&dev->dev_ctx_lock, flags); }static void mtk_vcodec_vpu_reset_enc_handler (void *priv) {struct mtk_vcodec_enc_dev *dev = priv;struct mtk_vcodec_enc_ctx *ctx; +unsigned long flags;dev_err (&dev->plat_dev->dev,"Watchdog timeout!!" ); -mutex_lock (&dev->dev_ctx_lock); +spin_lock_irqsave (&dev->dev_ctx_lock, flags);list_for_each_entry (ctx, &dev->ctx_list, list) { ctx->state =MTK_STATE_ABORT ;mtk_v4l2_vdec_dbg (0 , ctx,"[%d] Change to state MTK_STATE_ABORT" , ctx->id); } -mutex_unlock (&dev->dev_ctx_lock); +spin_unlock_irqrestore (&dev->dev_ctx_lock, flags); }static const struct mtk_vcodec_fw_ops mtk_vcodec_vpu_msg = {
drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c +7 -5
@@ -198,6 +198,7 @@ static int fops_vcodec_open(struct filestruct mtk_vcodec_dec_ctx *ctx =NULL ;int ret =0 , i, hw_count;struct vb2_queue *src_vq; +unsigned long flags; ctx =kzalloc (sizeof (*ctx),GFP_KERNEL );if (!ctx)
@@ -268,9 +269,9 @@ static int fops_vcodec_open(struct file ctx->dev->vdec_pdata->init_vdec_params (ctx); -mutex_lock (&dev->dev_ctx_lock); +spin_lock_irqsave (&dev->dev_ctx_lock, flags);list_add (&ctx->list, &dev->ctx_list); -mutex_unlock (&dev->dev_ctx_lock); +spin_unlock_irqrestore (&dev->dev_ctx_lock, flags);mtk_vcodec_dbgfs_create (ctx);mutex_unlock (&dev->dev_mutex);
@@ -295,6 +296,7 @@ static int fops_vcodec_release(struct fi {struct mtk_vcodec_dec_dev *dev =video_drvdata (file);struct mtk_vcodec_dec_ctx *ctx =fh_to_dec_ctx (file->private_data); +unsigned long flags;mtk_v4l2_vdec_dbg (0 , ctx,"[%d] decoder" , ctx->id);mutex_lock (&dev->dev_mutex);
@@ -313,9 +315,9 @@ static int fops_vcodec_release(struct fiv4l2_ctrl_handler_free (&ctx->ctrl_hdl);mtk_vcodec_dbgfs_remove (dev, ctx->id); -mutex_lock (&dev->dev_ctx_lock); +spin_lock_irqsave (&dev->dev_ctx_lock, flags);list_del_init (&ctx->list); -mutex_unlock (&dev->dev_ctx_lock); +spin_unlock_irqrestore (&dev->dev_ctx_lock, flags);kfree (ctx);mutex_unlock (&dev->dev_mutex);return 0 ;
@@ -382,7 +384,7 @@ static int mtk_vcodec_probe(struct platffor (i =0 ; i <MTK_VDEC_HW_MAX ; i++)mutex_init (&dev->dec_mutex[i]);mutex_init (&dev->dev_mutex); -mutex_init (&dev->dev_ctx_lock); +spin_lock_init (&dev->dev_ctx_lock);spin_lock_init (&dev->irqlock); snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h +1 -1
@@ -271,7 +271,7 @@ struct mtk_vcodec_dec_dev {/* decoder hardware mutex lock */ struct mutex dec_mutex[MTK_VDEC_HW_MAX ];struct mutex dev_mutex; -struct mutex dev_ctx_lock; +spinlock_t dev_ctx_lock;struct workqueue_struct *decode_workqueue;spinlock_t irqlock;
drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c +3 -2
@@ -75,16 +75,17 @@ static void handle_get_param_msg_ack(constatic bool vpu_dec_check_ap_inst (struct mtk_vcodec_dec_dev *dec_dev,struct vdec_vpu_inst *vpu) {struct mtk_vcodec_dec_ctx *ctx; +unsigned long flags;int ret = false; -mutex_lock (&dec_dev->dev_ctx_lock); +spin_lock_irqsave (&dec_dev->dev_ctx_lock, flags);list_for_each_entry (ctx, &dec_dev->ctx_list, list) {if (!IS_ERR_OR_NULL (ctx) && ctx->vpu_inst == vpu) { ret = true;break ; } } -mutex_unlock (&dec_dev->dev_ctx_lock); +spin_unlock_irqrestore (&dec_dev->dev_ctx_lock, flags);return ret; }
drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c +7 -5
@@ -117,6 +117,7 @@ static int fops_vcodec_open(struct filestruct mtk_vcodec_enc_ctx *ctx =NULL ;int ret =0 ;struct vb2_queue *src_vq; +unsigned long flags; ctx =kzalloc (sizeof (*ctx),GFP_KERNEL );if (!ctx)
@@ -177,9 +178,9 @@ static int fops_vcodec_open(struct filemtk_v4l2_venc_dbg (2 , ctx,"Create instance [%d]@%p m2m_ctx=%p " , ctx->id, ctx, ctx->m2m_ctx); -mutex_lock (&dev->dev_ctx_lock); +spin_lock_irqsave (&dev->dev_ctx_lock, flags);list_add (&ctx->list, &dev->ctx_list); -mutex_unlock (&dev->dev_ctx_lock); +spin_unlock_irqrestore (&dev->dev_ctx_lock, flags);mutex_unlock (&dev->dev_mutex); mtk_v4l2_venc_dbg(0, ctx, "%s encoder [%d]", dev_name(&dev->plat_dev->dev),
@@ -204,6 +205,7 @@ static int fops_vcodec_release(struct fi {struct mtk_vcodec_enc_dev *dev =video_drvdata (file);struct mtk_vcodec_enc_ctx *ctx =fh_to_enc_ctx (file->private_data); +unsigned long flags;mtk_v4l2_venc_dbg (1 , ctx,"[%d] encoder" , ctx->id);mutex_lock (&dev->dev_mutex);
@@ -214,9 +216,9 @@ static int fops_vcodec_release(struct fiv4l2_fh_exit (&ctx->fh);v4l2_ctrl_handler_free (&ctx->ctrl_hdl); -mutex_lock (&dev->dev_ctx_lock); +spin_lock_irqsave (&dev->dev_ctx_lock, flags);list_del_init (&ctx->list); -mutex_unlock (&dev->dev_ctx_lock); +spin_unlock_irqrestore (&dev->dev_ctx_lock, flags);kfree (ctx);mutex_unlock (&dev->dev_mutex);return 0 ;
@@ -298,7 +300,7 @@ static int mtk_vcodec_probe(struct platfmutex_init (&dev->enc_mutex);mutex_init (&dev->dev_mutex); -mutex_init (&dev->dev_ctx_lock); +spin_lock_init (&dev->dev_ctx_lock);spin_lock_init (&dev->irqlock); snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h +1 -1
@@ -206,7 +206,7 @@ struct mtk_vcodec_enc_dev {/* encoder hardware mutex lock */ struct mutex enc_mutex;struct mutex dev_mutex; -struct mutex dev_ctx_lock; +spinlock_t dev_ctx_lock;struct workqueue_struct *encode_workqueue;int enc_irq;
drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c +3 -2
@@ -45,16 +45,17 @@ static void handle_enc_encode_msg(structstatic bool vpu_enc_check_ap_inst (struct mtk_vcodec_enc_dev *enc_dev,struct venc_vpu_inst *vpu) {struct mtk_vcodec_enc_ctx *ctx; +unsigned long flags;int ret = false; -mutex_lock (&enc_dev->dev_ctx_lock); +spin_lock_irqsave (&enc_dev->dev_ctx_lock, flags);list_for_each_entry (ctx, &enc_dev->ctx_list, list) {if (!IS_ERR_OR_NULL (ctx) && ctx->vpu_inst == vpu) { ret = true;break ; } } -mutex_unlock (&enc_dev->dev_ctx_lock); +spin_unlock_irqrestore (&enc_dev->dev_ctx_lock, flags);return ret; }
Greg Kroah-Hartman
maintainerPATCH 702/737 KVM: SVM: Introduce svm_recalc_lbr_msr_intercepts()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yosry Ahmed <[email protected]>
Introduce a helper updating the intercepts for LBR MSRs, similar to the one introduced upstream by commit 160f143cc131 ("KVM: SVM: Manually recalc all MSR intercepts on userspace MSR filter change"). The main difference is that this version uses set_msr_interception(), which has inverted polarity compared to svm_set_intercept_for_msr().
This is intended to simplify incoming backports. No functional changes intended.
--- arch/x86/kvm/svm/svm.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-)
arch/x86/kvm/svm/svm.c +21 -11
@@ -1012,18 +1012,31 @@ void svm_copy_lbrs(struct vmcb *to_vmcb,vmcb_mark_dirty (to_vmcb,VMCB_LBR ); } -void svm_enable_lbrv (struct kvm_vcpu *vcpu) +static void svm_recalc_lbr_msr_intercepts (struct kvm_vcpu *vcpu) {struct vcpu_svm *svm =to_svm (vcpu); +bool intercept = !(svm->vmcb->control.virt_ext &LBR_CTL_ENABLE_MASK ); - svm->vmcb->control.virt_ext |=LBR_CTL_ENABLE_MASK ; -set_msr_interception (vcpu, svm->msrpm,MSR_IA32_LASTBRANCHFROMIP ,1 ,1 ); -set_msr_interception (vcpu, svm->msrpm,MSR_IA32_LASTBRANCHTOIP ,1 ,1 ); -set_msr_interception (vcpu, svm->msrpm,MSR_IA32_LASTINTFROMIP ,1 ,1 ); -set_msr_interception (vcpu, svm->msrpm,MSR_IA32_LASTINTTOIP ,1 ,1 ); +set_msr_interception (vcpu, svm->msrpm,MSR_IA32_LASTBRANCHFROMIP , + !intercept, !intercept); +set_msr_interception (vcpu, svm->msrpm,MSR_IA32_LASTBRANCHTOIP , + !intercept, !intercept); +set_msr_interception (vcpu, svm->msrpm,MSR_IA32_LASTINTFROMIP , + !intercept, !intercept); +set_msr_interception (vcpu, svm->msrpm,MSR_IA32_LASTINTTOIP , + !intercept, !intercept);if (sev_es_guest (vcpu->kvm)) -set_msr_interception (vcpu, svm->msrpm,MSR_IA32_DEBUGCTLMSR ,1 ,1 ); +set_msr_interception (vcpu, svm->msrpm,MSR_IA32_DEBUGCTLMSR , + !intercept, !intercept); +} + +void svm_enable_lbrv (struct kvm_vcpu *vcpu) +{ +struct vcpu_svm *svm =to_svm (vcpu); + + svm->vmcb->control.virt_ext |=LBR_CTL_ENABLE_MASK ; +svm_recalc_lbr_msr_intercepts (vcpu);/* Move the LBR msrs to the vmcb02 so that the guest can see them. */ if (is_guest_mode (vcpu))
@@ -1037,10 +1050,7 @@ static void svm_disable_lbrv(struct kvm_KVM_BUG_ON (sev_es_guest (vcpu->kvm), vcpu->kvm); svm->vmcb->control.virt_ext &= ~LBR_CTL_ENABLE_MASK ; -set_msr_interception (vcpu, svm->msrpm,MSR_IA32_LASTBRANCHFROMIP ,0 ,0 ); -set_msr_interception (vcpu, svm->msrpm,MSR_IA32_LASTBRANCHTOIP ,0 ,0 ); -set_msr_interception (vcpu, svm->msrpm,MSR_IA32_LASTINTFROMIP ,0 ,0 ); -set_msr_interception (vcpu, svm->msrpm,MSR_IA32_LASTINTTOIP ,0 ,0 ); +svm_recalc_lbr_msr_intercepts (vcpu);/* * Move the LBR msrs back to the vmcb01 to avoid copying them
Greg Kroah-Hartman
maintainerPATCH 703/737 KVM: nSVM: Always recalculate LBR MSR intercepts in svm_update_lbrv()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yosry Ahmed <[email protected]>
commit fbe5e5f030c22ae717ee422aaab0e00ea84fab5e upstream.
svm_update_lbrv() is called when MSR_IA32_DEBUGCTLMSR is updated, and on nested transitions where LBRV is used. It checks whether LBRV enablement needs to be changed in the current VMCB, and if it does, it also recalculate intercepts to LBR MSRs.
However, there are cases where intercepts need to be updated even when LBRV enablement doesn't. Example scenario:
- L1 has MSR_IA32_DEBUGCTLMSR cleared.
- L1 runs L2 without LBR_CTL_ENABLE (no LBRV).
- L2 sets DEBUGCTLMSR_LBR in MSR_IA32_DEBUGCTLMSR, svm_update_lbrv() sets LBR_CTL_ENABLE in VMCB02 and disables intercepts to LBR MSRs.
- L2 exits to L1, svm_update_lbrv() is not called on this transition.
- L1 clears MSR_IA32_DEBUGCTLMSR, svm_update_lbrv() finds that LBR_CTL_ENABLE is already cleared in VMCB01 and does nothing.
- Intercepts remain disabled, L1 reads to LBR MSRs read the host MSRs.
Fix it by always recalculating intercepts in svm_update_lbrv().
--- arch/x86/kvm/svm/svm.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-)
arch/x86/kvm/svm/svm.c +19 -10
@@ -1031,26 +1031,30 @@ static void svm_recalc_lbr_msr_intercept !intercept, !intercept); } -void svm_enable_lbrv (struct kvm_vcpu *vcpu) +static void __svm_enable_lbrv (struct kvm_vcpu *vcpu) {struct vcpu_svm *svm =to_svm (vcpu); svm->vmcb->control.virt_ext |=LBR_CTL_ENABLE_MASK ; -svm_recalc_lbr_msr_intercepts (vcpu);/* Move the LBR msrs to the vmcb02 so that the guest can see them. */ if (is_guest_mode (vcpu))svm_copy_lbrs (svm->vmcb, svm->vmcb01.ptr); } -static void svm_disable_lbrv (struct kvm_vcpu *vcpu) +void svm_enable_lbrv (struct kvm_vcpu *vcpu) +{ +__svm_enable_lbrv (vcpu); +svm_recalc_lbr_msr_intercepts (vcpu); +} + +static void __svm_disable_lbrv (struct kvm_vcpu *vcpu) {struct vcpu_svm *svm =to_svm (vcpu);KVM_BUG_ON (sev_es_guest (vcpu->kvm), vcpu->kvm); svm->vmcb->control.virt_ext &= ~LBR_CTL_ENABLE_MASK ; -svm_recalc_lbr_msr_intercepts (vcpu);/* * Move the LBR msrs back to the vmcb01 to avoid copying them
@@ -1079,13 +1083,18 @@ void svm_update_lbrv(struct kvm_vcpu *vc (is_guest_mode (vcpu) &&guest_can_use (vcpu,X86_FEATURE_LBRV ) && (svm->nested.ctl.virt_ext &LBR_CTL_ENABLE_MASK )); -if (enable_lbrv == current_enable_lbrv) -return ; +if (enable_lbrv && !current_enable_lbrv) +__svm_enable_lbrv (vcpu); +else if (!enable_lbrv && current_enable_lbrv) +__svm_disable_lbrv (vcpu); -if (enable_lbrv) -svm_enable_lbrv (vcpu); -else -svm_disable_lbrv (vcpu); +/* +* During nested transitions, it is possible that the current VMCB has +* LBR_CTL set, but the previous LBR_CTL had it cleared (or vice versa). +* In this case, even though LBR_CTL does not need an update, intercepts +* do, so always recalculate the intercepts here. +*/ +svm_recalc_lbr_msr_intercepts (vcpu); }void disable_nmi_singlestep (struct vcpu_svm *svm)
Greg Kroah-Hartman
maintainerPATCH 704/737 KVM: nSVM: Fix and simplify LBR virtualization handling with nested
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yosry Ahmed <[email protected]>
commit 8a4821412cf2c1429fffa07c012dd150f2edf78c upstream.
The current scheme for handling LBRV when nested is used is very complicated, especially when L1 does not enable LBRV (i.e. does not set LBR_CTL_ENABLE_MASK).
To avoid copying LBRs between VMCB01 and VMCB02 on every nested transition, the current implementation switches between using VMCB01 or VMCB02 as the source of truth for the LBRs while L2 is running. If L2 enables LBR, VMCB02 is used as the source of truth. When L2 disables LBR, the LBRs are copied to VMCB01 and VMCB01 is used as the source of truth. This introduces significant complexity, and incorrect behavior in some cases.
For example, on a nested #VMEXIT, the LBRs are only copied from VMCB02 to VMCB01 if LBRV is enabled in VMCB01. This is because L2's writes to MSR_IA32_DEBUGCTLMSR to enable LBR are intercepted and propagated to VMCB01 instead of VMCB02. However, LBRV is only enabled in VMCB02 when L2 is running.
This means that if L2 enables LBR and exits to L1, the LBRs will not be propagated from VMCB02 to VMCB01, because LBRV is disabled in VMCB01.
There is no meaningful difference in CPUID rate in L2 when copying LBRs on every nested transition vs. the current approach, so do the simple and correct thing and always copy LBRs between VMCB01 and VMCB02 on nested transitions (when LBRV is disabled by L1). Drop the conditional LBRs copying in __svm_{enable/disable}_lbrv() as it is now unnecessary.
VMCB02 becomes the only source of truth for LBRs when L2 is running, regardless of LBRV being enabled by L1, drop svm_get_lbr_vmcb() and use svm->vmcb directly in its place.
--- arch/x86/kvm/svm/nested.c | 20 ++++++------------- arch/x86/kvm/svm/svm.c | 47 +++++++++------------------------------------- 2 files changed, 17 insertions(+), 50 deletions(-)
arch/x86/kvm/svm/nested.c +7 -13
@@ -601,11 +601,10 @@ static void nested_vmcb02_prepare_save(s*/ svm_copy_lbrs (vmcb02, vmcb12); vmcb02->save.dbgctl &= ~DEBUGCTL_RESERVED_BITS ; -svm_update_lbrv (&svm->vcpu); - - }else if (unlikely (vmcb01->control.virt_ext &LBR_CTL_ENABLE_MASK )) { + }else {svm_copy_lbrs (vmcb02, vmcb01); } +svm_update_lbrv (&svm->vcpu); }static inline bool is_evtinj_soft (u32 evtinj)
@@ -731,11 +730,7 @@ static void nested_vmcb02_prepare_contro svm->soft_int_next_rip = vmcb12_rip; } - vmcb02->control.virt_ext = vmcb01->control.virt_ext & -LBR_CTL_ENABLE_MASK ; -if (guest_can_use (vcpu,X86_FEATURE_LBRV )) - vmcb02->control.virt_ext |= - (svm->nested.ctl.virt_ext &LBR_CTL_ENABLE_MASK ); +/* LBR_CTL_ENABLE_MASK is controlled by svm_update_lbrv() */ if (!nested_vmcb_needs_vls_intercept (svm)) vmcb02->control.virt_ext |=VIRTUAL_VMLOAD_VMSAVE_ENABLE_MASK ;
@@ -1066,13 +1061,12 @@ int nested_svm_vmexit(struct vcpu_svm *skvm_make_request (KVM_REQ_EVENT , &svm->vcpu);if (unlikely (guest_can_use (vcpu,X86_FEATURE_LBRV ) && - (svm->nested.ctl.virt_ext &LBR_CTL_ENABLE_MASK ))) { + (svm->nested.ctl.virt_ext &LBR_CTL_ENABLE_MASK )))svm_copy_lbrs (vmcb12, vmcb02); -svm_update_lbrv (vcpu); - }else if (unlikely (vmcb01->control.virt_ext &LBR_CTL_ENABLE_MASK )) { +else svm_copy_lbrs (vmcb01, vmcb02); -svm_update_lbrv (vcpu); - } + +svm_update_lbrv (vcpu);if (vnmi) {if (vmcb02->control.int_ctl &V_NMI_BLOCKING_MASK )
arch/x86/kvm/svm/svm.c +10 -37
88 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 705/737 KVM: SVM: Fix redundant updates of LBR MSR intercepts
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yosry Ahmed <[email protected]>
commit 3fa05f96fc08dff5e846c2cc283a249c1bf029a1 upstream.
Don't update the LBR MSR intercept bitmaps if they're already up-to-date, as unconditionally updating the intercepts forces KVM to recalculate the MSR bitmaps for vmcb02 on every nested VMRUN. The redundant updates are functionally okay; however, they neuter an optimization in Hyper-V nested virtualization enlightenments and this manifests as a self-test failure.
In particular, Hyper-V lets L1 mark "nested enlightenments" as clean, i.e. tell KVM that no changes were made to the MSR bitmap since the last VMRUN. The hyperv_svm_test KVM selftest intentionally changes the MSR bitmap "without telling KVM about it" to verify that KVM honors the clean hint, correctly fails because KVM notices the changed bitmap anyway:
==== Test Assertion Failure ==== x86/hyperv_svm_test.c:120: vmcb->control.exit_code == 0x081 pid=193558 tid=193558 errno=4 - Interrupted system call
1 0x0000000000411361: assert_on_unhandled_exception at processor.c:659
2 0x0000000000406186: _vcpu_run at kvm_util.c:1699
3 (inlined by) vcpu_run at kvm_util.c:1710
4 0x0000000000401f2a: main at hyperv_svm_test.c:175
5 0x000000000041d0d3: __libc_start_call_main at libc-start.o:?
6 0x000000000041f27c: __libc_start_main_impl at ??:?
7 0x00000000004021a0: _start at ??:? vmcb->control.exit_code == SVM_EXIT_VMMCALL
Do *not* fix this by skipping svm_hv_vmcb_dirty_nested_enlightenments() when svm_set_intercept_for_msr() performs a no-op change. changes to the L0 MSR interception bitmap are only triggered by full CPUID updates and MSR filter updates, both of which should be rare. Changing svm_set_intercept_for_msr() risks hiding unintended pessimizations like this one, and is actually more complex than this change.
--- arch/x86/kvm/svm/svm.c | 6 ++++++ arch/x86/kvm/svm/svm.h | 1 + 2 files changed, 7 insertions(+)
arch/x86/kvm/svm/svm.c +6 -0
@@ -1017,6 +1017,9 @@ static void svm_recalc_lbr_msr_interceptstruct vcpu_svm *svm =to_svm (vcpu);bool intercept = !(svm->vmcb->control.virt_ext &LBR_CTL_ENABLE_MASK ); +if (intercept == svm->lbr_msrs_intercepted) +return ; +set_msr_interception (vcpu, svm->msrpm,MSR_IA32_LASTBRANCHFROMIP , !intercept, !intercept); set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP,
@@ -1029,6 +1032,8 @@ static void svm_recalc_lbr_msr_interceptif (sev_es_guest (vcpu->kvm))set_msr_interception (vcpu, svm->msrpm,MSR_IA32_DEBUGCTLMSR , !intercept, !intercept); + + svm->lbr_msrs_intercepted = intercept; }static void __svm_enable_lbrv (struct kvm_vcpu *vcpu)
@@ -1473,6 +1478,7 @@ static int svm_vcpu_create(struct kvm_vc } svm->x2avic_msrs_intercepted = true; + svm->lbr_msrs_intercepted = true; svm->vmcb01.ptr =page_address (vmcb01_page); svm->vmcb01.pa =__sme_set (page_to_pfn (vmcb01_page) <<PAGE_SHIFT );
arch/x86/kvm/svm/svm.h +1 -0
@@ -288,6 +288,7 @@ struct vcpu_svm {bool guest_state_loaded;bool x2avic_msrs_intercepted; +bool lbr_msrs_intercepted;/* Guest GIF value, used when vGIF is not enabled */ bool guest_gif;
Greg Kroah-Hartman
maintainerPATCH 706/737 mm/damon/tests/vaddr-kunit: handle alloc failures in damon_test_split_evenly_fail()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit 7890e5b5bb6e386155c6e755fe70e0cdcc77f18e upstream.
damon_test_split_evenly_fail() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/vaddr-test.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
mm/damon/vaddr-test.h +10 -1
@@ -250,7 +250,16 @@ static void damon_test_split_evenly_fail unsigned long start, unsigned long end, unsigned int nr_pieces) { struct damon_target *t = damon_new_target(); -struct damon_region *r =damon_new_region (start, end); +struct damon_region *r; + +if (!t) +kunit_skip (test,"target alloc fail" ); + + r =damon_new_region (start, end); +if (!r) { +damon_free_target (t); +kunit_skip (test,"region alloc fail" ); + }damon_add_region (r, t); KUNIT_EXPECT_EQ(test,
Greg Kroah-Hartman
maintainerPATCH 707/737 mm/damon/tests/vaddr-kunit: handle alloc failures on damon_do_test_apply_three_regions()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit 2b22d0fcc6320ba29b2122434c1d2f0785fb0a25 upstream.
damon_do_test_apply_three_regions() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/vaddr-test.h | 6 ++++++ 1 file changed, 6 insertions(+)
mm/damon/vaddr-test.h +6 -0
@@ -136,8 +136,14 @@ static void damon_do_test_apply_three_reint i; t =damon_new_target (); +if (!t) +kunit_skip (test,"target alloc fail" );for (i =0 ; i < nr_regions /2 ; i++) { r =damon_new_region (regions[i *2 ], regions[i *2 +1 ]); +if (!r) { +damon_destroy_target (t); +kunit_skip (test,"region alloc fail" ); + }damon_add_region (r, t); }
Greg Kroah-Hartman
maintainerPATCH 708/737 RDMA/core: Fix "KASAN: slab-use-after-free Read in ib_register_device" problem
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhu Yanjun <[email protected]>
commit d0706bfd3ee40923c001c6827b786a309e2a8713 upstream.
Call Trace: __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x116/0x1f0 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:408 [inline] print_report+0xc3/0x670 mm/kasan/report.c:521 kasan_report+0xe0/0x110 mm/kasan/report.c:634 strlen+0x93/0xa0 lib/string.c:420 __fortify_strlen include/linux/fortify-string.h:268 [inline] get_kobj_path_length lib/kobject.c:118 [inline] kobject_get_path+0x3f/0x2a0 lib/kobject.c:158 kobject_uevent_env+0x289/0x1870 lib/kobject_uevent.c:545 ib_register_device drivers/infiniband/core/device.c:1472 [inline] ib_register_device+0x8cf/0xe00 drivers/infiniband/core/device.c:1393 rxe_register_device+0x275/0x320 drivers/infiniband/sw/rxe/rxe_verbs.c:1552 rxe_net_add+0x8e/0xe0 drivers/infiniband/sw/rxe/rxe_net.c:550 rxe_newlink+0x70/0x190 drivers/infiniband/sw/rxe/rxe.c:225 nldev_newlink+0x3a3/0x680 drivers/infiniband/core/nldev.c:1796 rdma_nl_rcv_msg+0x387/0x6e0 drivers/infiniband/core/netlink.c:195 rdma_nl_rcv_skb.constprop.0.isra.0+0x2e5/0x450 netlink_unicast_kernel net/netlink/af_netlink.c:1313 [inline] netlink_unicast+0x53a/0x7f0 net/netlink/af_netlink.c:1339 netlink_sendmsg+0x8d1/0xdd0 net/netlink/af_netlink.c:1883 sock_sendmsg_nosec net/socket.c:712 [inline] __sock_sendmsg net/socket.c:727 [inline] ____sys_sendmsg+0xa95/0xc70 net/socket.c:2566 ___sys_sendmsg+0x134/0x1d0 net/socket.c:2620 __sys_sendmsg+0x16d/0x220 net/socket.c:2652 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcd/0x260 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f
This problem is similar to the problem that the
commit 1d6a9e7449e2 ("RDMA/core: Fix use-after-free when rename device name") fixes.
The root cause is: the function ib_device_rename() renames the name with lock. But in the function kobject_uevent(), this name is accessed without lock protection at the same time.
The solution is to add the lock protection when this name is accessed in the function kobject_uevent().
[ Ajay: Modified to apply on v5.10.y-v6.6.y
ib_device_notify_register() not present in v5.10.y-v6.6.y, so directly added lock for kobject_uevent() ]
--- drivers/infiniband/core/device.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/infiniband/core/device.c +5 -0
@@ -1450,8 +1450,13 @@ int ib_register_device(struct ib_devicereturn ret; }dev_set_uevent_suppress (&device->dev, false); + +down_read (&devices_rwsem); +/* Mark for userspace that device is ready */ kobject_uevent (&device->dev.kobj,KOBJ_ADD ); + +up_read (&devices_rwsem);ib_device_put (device);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 709/737 sched/fair: Small cleanup to sched_balance_newidle()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
commit e78e70dbf603c1425f15f32b455ca148c932f6c1 upstream.
Pull out the !sd check to simplify code.
--- kernel/sched/fair.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
kernel/sched/fair.c +6 -5
@@ -12374,14 +12374,15 @@ static int sched_balance_newidle(structrcu_read_lock (); sd =rcu_dereference_check_sched_domain (this_rq->sd); +if (!sd) { +rcu_read_unlock (); + goto out; + }if (!READ_ONCE (this_rq->rd->overload) || - (sd && this_rq->avg_idle < sd->max_newidle_lb_cost)) { - -if (sd) -update_next_balance (sd, &next_balance); + this_rq->avg_idle < sd->max_newidle_lb_cost) { +update_next_balance (sd, &next_balance);rcu_read_unlock (); - goto out; }rcu_read_unlock ();
Greg Kroah-Hartman
maintainerPATCH 710/737 sched/fair: Small cleanup to update_newidle_cost()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
commit 08d473dd8718e4a4d698b1113a14a40ad64a909b upstream.
Simplify code by adding a few variables.
--- kernel/sched/fair.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
kernel/sched/fair.c +7 -4
@@ -11718,22 +11718,25 @@ void update_max_interval(void)static inline bool update_newidle_cost (struct sched_domain *sd,u64 cost) { +unsigned long next_decay = sd->last_decay_max_lb_cost +HZ ; +unsigned long now = jiffies; +if (cost > sd->max_newidle_lb_cost) {/* * Track max cost of a domain to make sure to not delay the * next wakeup on the CPU. */ sd->max_newidle_lb_cost = cost; - sd->last_decay_max_lb_cost = jiffies; - }else if (time_after (jiffies, sd->last_decay_max_lb_cost +HZ )) { + sd->last_decay_max_lb_cost = now; + + }else if (time_after (now, next_decay)) {/* * Decay the newidle max times by ~1% per second to ensure that * it is not outdated and the current max cost is actually * shorter. */ sd->max_newidle_lb_cost = (sd->max_newidle_lb_cost *253 ) /256 ; - sd->last_decay_max_lb_cost = jiffies; - + sd->last_decay_max_lb_cost = now;return true; }
Greg Kroah-Hartman
maintainerPATCH 711/737 sched/fair: Proportional newidle balance
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra (Intel) <[email protected]>
commit 33cf66d88306663d16e4759e9d24766b0aaa2e17 upstream.
Add a randomized algorithm that runs newidle balancing proportional to its success rate.
This improves schbench significantly:
6.18-rc4: 2.22 Mrps/s
6.18-rc4+revert: 2.04 Mrps/s
6.18-rc4+revert+random: 2.18 Mrps/S
Conversely, per Adam Li this affects SpecJBB slightly, reducing it by 1%:
6.17: -6%
6.17+revert: 0%
6.17+revert+random: -1%
--- include/linux/sched/topology.h | 3 ++ kernel/sched/core.c | 3 ++ kernel/sched/fair.c | 44 +++++++++++++++++++++++++++++++++++++---- kernel/sched/features.h | 5 ++++ kernel/sched/sched.h | 7 ++++++ kernel/sched/topology.c | 6 +++++ 6 files changed, 64 insertions(+), 4 deletions(-)
include/linux/sched/topology.h +3 -0
@@ -106,6 +106,9 @@ struct sched_domain {unsigned int nr_balance_failed;/* initialise to 0 */ /* idle_balance() stats */ +unsigned int newidle_call; +unsigned int newidle_success; +unsigned int newidle_ratio;u64 max_newidle_lb_cost;unsigned long last_decay_max_lb_cost;
kernel/sched/core.c +3 -0
@@ -116,6 +116,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(sched_util_EXPORT_TRACEPOINT_SYMBOL_GPL (sched_update_nr_running_tp); DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues); +DEFINE_PER_CPU(struct rnd_state, sched_rnd_state);#ifdef CONFIG_SCHED_DEBUG /*
@@ -9872,6 +9873,8 @@ void __init sched_init_smp(void) {sched_init_numa (NUMA_NO_NODE ); +prandom_init_once (&sched_rnd_state); +/* * There's no userspace yet to cause hotplug operations; hence all the * CPU masks are stable and all blatant races in the below code cannot
kernel/sched/fair.c +40 -4
74 lines not on this page · raw message
kernel/sched/features.h +5 -0
@@ -88,4 +88,9 @@ SCHED_FEAT(UTIL_EST_FASTUP, true)SCHED_FEAT (LATENCY_WARN , false) +/* +* Do newidle balancing proportional to its success rate using randomization. + */ +SCHED_FEAT(NI_RANDOM, true) +SCHED_FEAT (HZ_BW , true)
kernel/sched/sched.h +7 -0
@@ -5,6 +5,7 @@#ifndef _KERNEL_SCHED_SCHED_H#define _KERNEL_SCHED_SCHED_H +#include <linux/prandom.h> #include <linux/sched/affinity.h> #include <linux/sched/autogroup.h> #include <linux/sched/cpufreq.h>
@@ -1205,6 +1206,12 @@ static inline bool is_migration_disabled } DECLARE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues); +DECLARE_PER_CPU(struct rnd_state, sched_rnd_state); + +static inline u32 sched_rng (void ) +{ +return prandom_u32_state (this_cpu_ptr (&sched_rnd_state)); +}#define cpu_rq (cpu) (&per_cpu(runqueues, (cpu)))#define this_rq () this_cpu_ptr(&runqueues)
kernel/sched/topology.c +6 -0
@@ -1600,6 +1600,12 @@ sd_init(struct sched_domain_topology_lev .last_balance = jiffies, .balance_interval = sd_weight, + +/* 50% success rate */ + .newidle_call = 512, + .newidle_success = 256, + .newidle_ratio = 512, + .max_newidle_lb_cost = 0, .last_decay_max_lb_cost = jiffies, .child = child,
Greg Kroah-Hartman
maintainerPATCH 712/737 net: Remove conditional threaded-NAPI wakeup based on task state.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
commit 56364c910691f6d10ba88c964c9041b9ab777bd6 upstream.
A NAPI thread is scheduled by first setting NAPI_STATE_SCHED bit. If successful (the bit was not yet set) then the NAPI_STATE_SCHED_THREADED is set but only if thread's state is not TASK_INTERRUPTIBLE (is TASK_RUNNING) followed by task wakeup.
If the task is idle (TASK_INTERRUPTIBLE) then the NAPI_STATE_SCHED_THREADED bit is not set. The thread is no relying on the bit but always leaving the wait-loop after returning from schedule() because there must have been a wakeup.
The smpboot-threads implementation for per-CPU threads requires an explicit condition and does not support "if we get out of schedule() then there must be something to do".
Removing this optimisation simplifies the following integration.
Set NAPI_STATE_SCHED_THREADED unconditionally on wakeup and rely on it in the wait path by removing the `woken' condition.
--- net/core/dev.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-)
net/core/dev.c +2 -12
@@ -4526,13 +4526,7 @@ static inline void ____napi_schedule(str*/ thread =READ_ONCE (napi->thread);if (thread) { -/* Avoid doing set_bit() if the thread is in -* INTERRUPTIBLE state, cause napi_thread_wait() -* makes sure to proceed with napi polling -* if the thread is explicitly woken from here. -*/ -if (READ_ONCE (thread->__state) !=TASK_INTERRUPTIBLE ) -set_bit (NAPI_STATE_SCHED_THREADED , &napi->state); +set_bit (NAPI_STATE_SCHED_THREADED , &napi->state);wake_up_process (thread);return ; }
@@ -6688,8 +6682,6 @@ static int napi_poll(struct napi_structstatic int napi_thread_wait (struct napi_struct *napi) { -bool woken = false; -set_current_state (TASK_INTERRUPTIBLE );while (!kthread_should_stop ()) {
@@ -6698,15 +6690,13 @@ static int napi_thread_wait(struct napi_* Testing SCHED bit is not enough because SCHED bit might be * set by some other busy poll thread or by napi_disable(). */ -if (test_bit (NAPI_STATE_SCHED_THREADED , &napi->state) || woken) { +if (test_bit (NAPI_STATE_SCHED_THREADED , &napi->state)) {WARN_ON (!list_empty (&napi->poll_list));__set_current_state (TASK_RUNNING );return 0 ; }schedule (); -/* woken being true indicates this thread owns this napi. */ - woken = true;set_current_state (TASK_INTERRUPTIBLE ); }__set_current_state (TASK_RUNNING );
Greg Kroah-Hartman
maintainerPATCH 713/737 net: Allow to use SMP threads for backlog NAPI.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
commit dad6b97702639fba27a2bd3e986982ad6f0db3a7 upstream.
Backlog NAPI is a per-CPU NAPI struct only (with no device behind it) used by drivers which don't do NAPI them self, RPS and parts of the stack which need to avoid recursive deadlocks while processing a packet.
The non-NAPI driver use the CPU local backlog NAPI. If RPS is enabled then a flow for the skb is computed and based on the flow the skb can be enqueued on a remote CPU. Scheduling/ raising the softirq (for backlog's NAPI) on the remote CPU isn't trivial because the softirq is only scheduled on the local CPU and performed after the hardirq is done. In order to schedule a softirq on the remote CPU, an IPI is sent to the remote CPU which schedules the backlog-NAPI on the then local CPU.
On PREEMPT_RT interrupts are force-threaded. The soft interrupts are raised within the interrupt thread and processed after the interrupt handler completed still within the context of the interrupt thread. The softirq is handled in the context where it originated.
With force-threaded interrupts enabled, ksoftirqd is woken up if a softirq is raised from hardirq context. This is the case if it is raised from an IPI. Additionally there is a warning on PREEMPT_RT if the softirq is raised from the idle thread.
This was done for two reasons:
- With threaded interrupts the processing should happen in thread context (where it originated) and ksoftirqd is the only thread for this context if raised from hardirq. Using the currently running task instead would "punish" a random task.
- Once ksoftirqd is active it consumes all further softirqs until it stops running. This changed recently and is no longer the case.
Instead of keeping the backlog NAPI in ksoftirqd (in force-threaded/ PREEMPT_RT setups) I am proposing NAPI-threads for backlog. The "proper" setup with threaded-NAPI is not doable because the threads are not pinned to an individual CPU and can be modified by the user. Additionally a dummy network device would have to be assigned. Also CPU-hotplug has to be considered if additional CPUs show up. All this can be probably done/ solved but the smpboot-threads already provide this infrastructure.
Sending UDP packets over loopback expects that the packet is processed within the call. Delaying it by handing it over to the thread hurts performance. It is not beneficial to the outcome if the context switch happens immediately after enqueue or after a while to process a few packets in a batch.
There is no need to always use the thread if the backlog NAPI is requested on the local CPU. This restores the loopback throuput. The performance drops mostly to the same value after enabling RPS on the loopback comparing the IPI and the tread result.
Create NAPI-threads for backlog if request during boot. The thread runs the inner loop from napi_threaded_poll(), the wait part is different. It checks for NAPI_STATE_SCHED (the backlog NAPI can not be disabled).
The NAPI threads for backlog are optional, it has to be enabled via the boot argument "thread_backlog_napi". It is mandatory for PREEMPT_RT to avoid the wakeup of ksoftirqd from the IPI.
--- net/core/dev.c | 152 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 115 insertions(+), 37 deletions(-)
net/core/dev.c +115 -37
@@ -78,6 +78,7 @@#include <linux/slab.h> #include <linux/sched.h> #include <linux/sched/mm.h> +#include <linux/smpboot.h> #include <linux/mutex.h> #include <linux/rwsem.h> #include <linux/string.h>
@@ -217,6 +218,31 @@ static inline struct hlist_head *dev_indreturn &net->dev_index_head[ifindex & (NETDEV_HASHENTRIES -1 )]; } +#ifndef CONFIG_PREEMPT_RT + +static DEFINE_STATIC_KEY_FALSE (use_backlog_threads_key); + +static int __init setup_backlog_napi_threads (char *arg) +{ +static_branch_enable (&use_backlog_threads_key); +return 0 ; +} +early_param ("thread_backlog_napi" , setup_backlog_napi_threads); + +static bool use_backlog_threads (void ) +{ +return static_branch_unlikely (&use_backlog_threads_key); +} + +#else + +static bool use_backlog_threads (void ) +{ +return true; +} + +#endif +static inline void rps_lock_irqsave (struct softnet_data *sd,unsigned long *flags) {
@@ -4494,6 +4520,7 @@ EXPORT_SYMBOL(__dev_direct_xmit);/************************************************************************* * Receiver routines *************************************************************************/ +static DEFINE_PER_CPU(struct task_struct *, backlog_napi);int netdev_max_backlog__read_mostly =1000 ;EXPORT_SYMBOL (netdev_max_backlog);
@@ -4526,12 +4553,16 @@ static inline void ____napi_schedule(str*/ thread =READ_ONCE (napi->thread);if (thread) { +if (use_backlog_threads () && thread ==raw_cpu_read (backlog_napi)) + goto use_local_napi; +set_bit (NAPI_STATE_SCHED_THREADED , &napi->state);wake_up_process (thread);return ; } } +use_local_napi:list_add_tail (&napi->poll_list, &sd->poll_list);WRITE_ONCE (napi->list_owner,smp_processor_id ());/* If not called from net_rx_action()
@@ -4777,6 +4808,11 @@ static void napi_schedule_rps(struct sof#ifdef CONFIG_RPS if (sd != mysd) { +if (use_backlog_threads ()) { +__napi_schedule_irqoff (&sd->backlog); +return ; + } + sd->rps_ipi_next = mysd->rps_ipi_list; mysd->rps_ipi_list = sd;
@@ -6000,7 +6036,7 @@ static void net_rps_action_and_irq_enabl#ifdef CONFIG_RPS struct softnet_data *remsd = sd->rps_ipi_list; -if (remsd) { +if (!use_backlog_threads () && remsd) { sd->rps_ipi_list =NULL ;local_irq_enable ();
@@ -6015,7 +6051,7 @@ static void net_rps_action_and_irq_enablstatic bool sd_has_rps_ipi_waiting (struct softnet_data *sd) {#ifdef CONFIG_RPS -return sd->rps_ipi_list !=NULL ; +return !use_backlog_threads () && sd->rps_ipi_list;#else return false;#endif
@@ -6059,7 +6095,7 @@ static int process_backlog(struct napi_s* We can use a plain write instead of clear_bit(), * and we dont need an smp_mb() memory barrier. */ - napi->state =0 ; + napi->state &=NAPIF_STATE_THREADED ; again = false; }else { skb_queue_splice_tail_init(&sd->input_pkt_queue,
@@ -6725,43 +6761,48 @@ static void skb_defer_free_flush(struct } } -static int napi_threaded_poll (void *data) +static void napi_threaded_poll_loop (struct napi_struct *napi) { -struct napi_struct *napi = data;struct softnet_data *sd; -void *have; +unsigned long last_qs = jiffies; -while (!napi_thread_wait (napi)) { -unsigned long last_qs = jiffies; +for (;;) { +bool repoll = false; +void *have; -for (;;) { -bool repoll = false; +local_bh_disable (); + sd =this_cpu_ptr (&softnet_data); + sd->in_napi_threaded_poll = true; -local_bh_disable (); - sd =this_cpu_ptr (&softnet_data); - sd->in_napi_threaded_poll = true; - - have =netpoll_poll_lock (napi); -__napi_poll (napi, &repoll); -netpoll_poll_unlock (have); - - sd->in_napi_threaded_poll = false; -barrier (); - -if (sd_has_rps_ipi_waiting (sd)) { -local_irq_disable (); -net_rps_action_and_irq_enable (sd); - } -skb_defer_free_flush (sd); -local_bh_enable (); + have =netpoll_poll_lock (napi); +__napi_poll (napi, &repoll); +netpoll_poll_unlock (have); + + sd->in_napi_threaded_poll = false; +barrier (); + +if (sd_has_rps_ipi_waiting (sd)) { +local_irq_disable (); +net_rps_action_and_irq_enable (sd); + } +skb_defer_free_flush (sd); +local_bh_enable (); -if (!repoll) -break ; +if (!repoll) +break ; -rcu_softirq_qs_periodic (last_qs); -cond_resched (); - } +rcu_softirq_qs_periodic (last_qs); +cond_resched (); } +} + +static int napi_threaded_poll (void *data) +{ +struct napi_struct *napi = data; + +while (!napi_thread_wait (napi)) +napi_threaded_poll_loop (napi); +return 0 ; }
@@ -11346,7 +11387,7 @@ static int dev_cpu_dead(unsigned int oldlist_del_init (&napi->poll_list);if (napi->poll == process_backlog) - napi->state =0 ; + napi->state &=NAPIF_STATE_THREADED ;else ____napi_schedule (sd, napi); }
@@ -11354,12 +11395,14 @@ static int dev_cpu_dead(unsigned int oldraise_softirq_irqoff (NET_TX_SOFTIRQ );local_irq_enable (); +if (!use_backlog_threads ()) {#ifdef CONFIG_RPS - remsd = oldsd->rps_ipi_list; - oldsd->rps_ipi_list =NULL ; + remsd = oldsd->rps_ipi_list; + oldsd->rps_ipi_list =NULL ;#endif -/* send out pending IPI's on offline CPU */ -net_rps_send_ipi (remsd); +/* send out pending IPI's on offline CPU */ +net_rps_send_ipi (remsd); + }/* Process offline CPU's input_pkt_queue */ while ((skb =__skb_dequeue (&oldsd->process_queue))) {
@@ -11622,6 +11665,38 @@ static struct pernet_operations __net_in* */ +static int backlog_napi_should_run (unsigned int cpu) +{ +struct softnet_data *sd =per_cpu_ptr (&softnet_data, cpu); +struct napi_struct *napi = &sd->backlog; + +return test_bit (NAPI_STATE_SCHED_THREADED , &napi->state); +} + +static void run_backlog_napi (unsigned int cpu) +{ +struct softnet_data *sd =per_cpu_ptr (&softnet_data, cpu); + +napi_threaded_poll_loop (&sd->backlog); +} + +static void backlog_napi_setup (unsigned int cpu) +{ +struct softnet_data *sd =per_cpu_ptr (&softnet_data, cpu); +struct napi_struct *napi = &sd->backlog; + + napi->thread =this_cpu_read (backlog_napi); +set_bit (NAPI_STATE_THREADED , &napi->state); +} + +static struct smp_hotplug_thread backlog_threads = { + .store = &backlog_napi, + .thread_should_run = backlog_napi_should_run, + .thread_fn = run_backlog_napi, + .thread_comm ="backlog_napi/%u" , + .setup = backlog_napi_setup, +}; +/* * This is called single threaded during boot, so no need * to take the rtnl semaphore.
@@ -11672,7 +11747,10 @@ static int __init net_dev_init(void)init_gro_hash (&sd->backlog); sd->backlog.poll = process_backlog; sd->backlog.weight = weight_p; +INIT_LIST_HEAD (&sd->backlog.poll_list); } +if (use_backlog_threads ()) +smpboot_register_percpu_thread (&backlog_threads); dev_boot_phase =0 ;
Greg Kroah-Hartman
maintainerPATCH 714/737 RDMA/rxe: Remove the direct link to net_device
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhu Yanjun <[email protected]>
[ Upstream commit 2ac5415022d16d63d912a39a06f32f1f51140261 ]
The similar patch in siw is in the link:
https://git.kernel.org/rdma/rdma/c/16b87037b48889
This problem also occurred in RXE. The following analyze this problem. In the following Call Traces:
"
BUG: KASAN: slab-use-after-free in dev_get_flags+0x188/0x1d0 net/core/dev.c:8782 Read of size 4 at addr ffff8880554640b0 by task kworker/1:4/5295 CPU: 1 UID: 0 PID: 5295 Comm: kworker/1:4 Not tainted 6.12.0-rc3-syzkaller-00399-g9197b73fd7bb #0 Hardware name: Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 Workqueue: infiniband ib_cache_event_task Call Trace: <TASK> __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:377 [inline] print_report+0x169/0x550 mm/kasan/report.c:488 kasan_report+0x143/0x180 mm/kasan/report.c:601 dev_get_flags+0x188/0x1d0 net/core/dev.c:8782 rxe_query_port+0x12d/0x260 drivers/infiniband/sw/rxe/rxe_verbs.c:60 __ib_query_port drivers/infiniband/core/device.c:2111 [inline] ib_query_port+0x168/0x7d0 drivers/infiniband/core/device.c:2143 ib_cache_update+0x1a9/0xb80 drivers/infiniband/core/cache.c:1494 ib_cache_event_task+0xf3/0x1e0 drivers/infiniband/core/cache.c:1568 process_one_work kernel/workqueue.c:3229 [inline] process_scheduled_works+0xa65/0x1850 kernel/workqueue.c:3310 worker_thread+0x870/0xd30 kernel/workqueue.c:3391 kthread+0x2f2/0x390 kernel/kthread.c:389 ret_from_fork+0x4d/0x80 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 </TASK>
"
1). In the link [1],
"
infiniband syz2: set down
"
This means that on 839.350575, the event ib_cache_event_task was sent andi queued in ib_wq.
2). In the link [1],
"
team0 (unregistering): Port device team_slave_0 removed
"
It indicates that before 843.251853, the net device should be freed.
3). In the link [1],
"
BUG: KASAN: slab-use-after-free in dev_get_flags+0x188/0x1d0
"
This means that on 850.559070, this slab-use-after-free problem occurred.
In all, on 839.350575, the event ib_cache_event_task was sent and queued in ib_wq,
before 843.251853, the net device veth was freed.
on 850.559070, this event was executed, and the mentioned freed net device was called. Thus, the above call trace occurred.
[1] https://syzkaller.appspot.com/x/log.txt?x=12e7025f980000
[Shivani: - exported ib_device_get_netdev() function.
- added ib_device_get_netdev() to ib_verbs.h.]
--- drivers/infiniband/core/device.c | 1 + drivers/infiniband/sw/rxe/rxe.c | 23 +++++++++++++++++++---- drivers/infiniband/sw/rxe/rxe.h | 3 ++- drivers/infiniband/sw/rxe/rxe_mcast.c | 22 ++++++++++++++++++++-- drivers/infiniband/sw/rxe/rxe_net.c | 25 ++++++++++++++++++++----- drivers/infiniband/sw/rxe/rxe_verbs.c | 26 +++++++++++++++++++++----- drivers/infiniband/sw/rxe/rxe_verbs.h | 11 ++++++++--- include/rdma/ib_verbs.h | 2 ++ 8 files changed, 93 insertions(+), 20 deletions(-)
drivers/infiniband/core/device.c +1 -0
@@ -2259,6 +2259,7 @@ struct net_device *ib_device_get_netdev(return res; } +EXPORT_SYMBOL (ib_device_get_netdev);/** * ib_device_get_by_netdev - Find an IB device associated with a netdev
drivers/infiniband/sw/rxe/rxe.c +19 -4
@@ -40,6 +40,8 @@ void rxe_dealloc(struct ib_device *ib_de/* initialize rxe device parameters */ static void rxe_init_device_param (struct rxe_dev *rxe) { +struct net_device *ndev; + rxe->max_inline_data =RXE_MAX_INLINE_DATA ; rxe->attr.vendor_id =RXE_VENDOR_ID ;
@@ -71,8 +73,15 @@ static void rxe_init_device_param(struct rxe->attr.max_fast_reg_page_list_len =RXE_MAX_FMR_PAGE_LIST_LEN ; rxe->attr.max_pkeys =RXE_MAX_PKEYS ; rxe->attr.local_ca_ack_delay =RXE_LOCAL_CA_ACK_DELAY ; + + ndev =rxe_ib_device_get_netdev (&rxe->ib_dev); +if (!ndev) +return ; +addrconf_addr_eui48 ((unsigned char *)&rxe->attr.sys_image_guid, - rxe->ndev->dev_addr); + ndev->dev_addr); + +dev_put (ndev); rxe->max_ucontext =RXE_MAX_UCONTEXT ; }
@@ -109,10 +118,15 @@ static void rxe_init_port_param(struct rstatic void rxe_init_ports (struct rxe_dev *rxe) {struct rxe_port *port = &rxe->port; +struct net_device *ndev;rxe_init_port_param (port); + ndev =rxe_ib_device_get_netdev (&rxe->ib_dev); +if (!ndev) +return ;addrconf_addr_eui48 ((unsigned char *)&port->port_guid, - rxe->ndev->dev_addr); + ndev->dev_addr); +dev_put (ndev);spin_lock_init (&port->port_lock); }
@@ -169,12 +183,13 @@ void rxe_set_mtu(struct rxe_dev *rxe, un/* called by ifc layer to create new rxe device. * The caller should allocate memory for rxe by calling ib_alloc_device. */ -int rxe_add (struct rxe_dev *rxe,unsigned int mtu,const char *ibdev_name) +int rxe_add (struct rxe_dev *rxe,unsigned int mtu,const char *ibdev_name, +struct net_device *ndev) {rxe_init (rxe);rxe_set_mtu (rxe, mtu); -return rxe_register_device (rxe, ibdev_name); +return rxe_register_device (rxe, ibdev_name, ndev); }static int rxe_newlink (const char *ibdev_name,struct net_device *ndev)
drivers/infiniband/sw/rxe/rxe.h +2 -1
@@ -139,7 +139,8 @@ enum resp_states {void rxe_set_mtu (struct rxe_dev *rxe,unsigned int dev_mtu); -int rxe_add (struct rxe_dev *rxe,unsigned int mtu,const char *ibdev_name); +int rxe_add (struct rxe_dev *rxe,unsigned int mtu,const char *ibdev_name, +struct net_device *ndev);void rxe_rcv (struct sk_buff *skb);
drivers/infiniband/sw/rxe/rxe_mcast.c +20 -2
@@ -31,10 +31,19 @@static int rxe_mcast_add (struct rxe_dev *rxe,union ib_gid *mgid) {unsigned char ll_addr[ETH_ALEN ]; +struct net_device *ndev; +int ret; + + ndev =rxe_ib_device_get_netdev (&rxe->ib_dev); +if (!ndev) +return -ENODEV ;ipv6_eth_mc_map ((struct in6_addr *)mgid->raw, ll_addr); -return dev_mc_add (rxe->ndev, ll_addr); + ret =dev_mc_add (ndev, ll_addr); +dev_put (ndev); + +return ret; }/**
@@ -47,10 +56,19 @@ static int rxe_mcast_add(struct rxe_devstatic int rxe_mcast_del (struct rxe_dev *rxe,union ib_gid *mgid) {unsigned char ll_addr[ETH_ALEN ]; +struct net_device *ndev; +int ret; + + ndev =rxe_ib_device_get_netdev (&rxe->ib_dev); +if (!ndev) +return -ENODEV ;ipv6_eth_mc_map ((struct in6_addr *)mgid->raw, ll_addr); -return dev_mc_del (rxe->ndev, ll_addr); + ret =dev_mc_del (ndev, ll_addr); +dev_put (ndev); + +return ret; }/**
drivers/infiniband/sw/rxe/rxe_net.c +20 -5
@@ -509,7 +509,16 @@ out:*/ const char *rxe_parent_name (struct rxe_dev *rxe,unsigned int port_num) { -return rxe->ndev->name; +struct net_device *ndev; +char *ndev_name; + + ndev =rxe_ib_device_get_netdev (&rxe->ib_dev); +if (!ndev) +return NULL ; + ndev_name = ndev->name; +dev_put (ndev); + +return ndev_name; }int rxe_net_add (const char *ibdev_name,struct net_device *ndev)
@@ -521,9 +530,7 @@ int rxe_net_add(const char *ibdev_name,if (!rxe)return -ENOMEM ; - rxe->ndev = ndev; - - err =rxe_add (rxe, ndev->mtu, ibdev_name); + err =rxe_add (rxe, ndev->mtu, ibdev_name, ndev);if (err) {ib_dealloc_device (&rxe->ib_dev);return err;
@@ -571,10 +578,18 @@ void rxe_port_down(struct rxe_dev *rxe)void rxe_set_port_state (struct rxe_dev *rxe) { -if (netif_running (rxe->ndev) &&netif_carrier_ok (rxe->ndev)) +struct net_device *ndev; + + ndev =rxe_ib_device_get_netdev (&rxe->ib_dev); +if (!ndev) +return ; + +if (netif_running (ndev) &&netif_carrier_ok (ndev))rxe_port_up (rxe);else rxe_port_down (rxe); + +dev_put (ndev); } static int rxe_notify(struct notifier_block *not_blk,
drivers/infiniband/sw/rxe/rxe_verbs.c +21 -5
@@ -41,6 +41,7 @@ static int rxe_query_port(struct ib_devi u32 port_num, struct ib_port_attr *attr) { struct rxe_dev *rxe = to_rdev(ibdev); +struct net_device *ndev;int err, ret;if (port_num !=1 ) {
@@ -51,19 +52,26 @@ static int rxe_query_port(struct ib_devimemcpy (attr, &rxe->port.attr,sizeof (*attr)); + ndev =rxe_ib_device_get_netdev (ibdev); +if (!ndev) { + err = -ENODEV ; + goto err_out; + } +mutex_lock (&rxe->usdev_lock); ret =ib_get_eth_speed (ibdev, port_num, &attr->active_speed, &attr->active_width);if (attr->state ==IB_PORT_ACTIVE ) attr->phys_state =IB_PORT_PHYS_STATE_LINK_UP ; -else if (dev_get_flags (rxe->ndev) &IFF_UP ) +else if (dev_get_flags (ndev) &IFF_UP ) attr->phys_state =IB_PORT_PHYS_STATE_POLLING ;else attr->phys_state =IB_PORT_PHYS_STATE_DISABLED ;mutex_unlock (&rxe->usdev_lock); +dev_put (ndev);return ret; err_out:
@@ -1428,9 +1436,16 @@ static const struct attribute_group rxe_static int rxe_enable_driver (struct ib_device *ib_dev) { struct rxe_dev *rxe = container_of(ib_dev, struct rxe_dev, ib_dev); +struct net_device *ndev; + + ndev =rxe_ib_device_get_netdev (ib_dev); +if (!ndev) +return -ENODEV ;rxe_set_port_state (rxe); -dev_info (&rxe->ib_dev.dev,"added %s\n" ,netdev_name (rxe->ndev)); +dev_info (&rxe->ib_dev.dev,"added %s\n" ,netdev_name (ndev)); + +dev_put (ndev);return 0 ; }
@@ -1498,7 +1513,8 @@ static const struct ib_device_ops rxe_de INIT_RDMA_OBJ_SIZE(ib_mw, rxe_mw, ibmw), }; -int rxe_register_device (struct rxe_dev *rxe,const char *ibdev_name) +int rxe_register_device (struct rxe_dev *rxe,const char *ibdev_name, +struct net_device *ndev) {int err;struct ib_device *dev = &rxe->ib_dev;
@@ -1510,13 +1526,13 @@ int rxe_register_device(struct rxe_dev * dev->num_comp_vectors =num_possible_cpus (); dev->local_dma_lkey =0 ;addrconf_addr_eui48 ((unsigned char *)&dev->node_guid, - rxe->ndev->dev_addr); + ndev->dev_addr); dev->uverbs_cmd_mask |=BIT_ULL (IB_USER_VERBS_CMD_POST_SEND ) |BIT_ULL (IB_USER_VERBS_CMD_REQ_NOTIFY_CQ );ib_set_device_ops (dev, &rxe_dev_ops); - err =ib_device_set_netdev (&rxe->ib_dev, rxe->ndev,1 ); + err =ib_device_set_netdev (&rxe->ib_dev, ndev,1 );if (err)return err;
drivers/infiniband/sw/rxe/rxe_verbs.h +8 -3
@@ -369,6 +369,7 @@ struct rxe_port {u32 qp_gsi_index; }; +#define RXE_PORT 1struct rxe_dev {struct ib_device ib_dev;struct ib_device_attr attr;
@@ -376,8 +377,6 @@ struct rxe_dev {int max_inline_data;struct mutex usdev_lock; -struct net_device *ndev; -struct rxe_pool uc_pool;struct rxe_pool pd_pool;struct rxe_pool ah_pool;
@@ -405,6 +404,11 @@ struct rxe_dev {struct crypto_shash *tfm; }; +static inline struct net_device *rxe_ib_device_get_netdev (struct ib_device *dev) +{ +return ib_device_get_netdev (dev,RXE_PORT ); +} +static inline void rxe_counter_inc (struct rxe_dev *rxe,enum rxe_counters index) {atomic64_inc (&rxe->stats_counters[index]);
@@ -470,6 +474,7 @@ static inline struct rxe_pd *rxe_mw_pd(s return to_rpd(mw->ibmw.pd); } -int rxe_register_device (struct rxe_dev *rxe,const char *ibdev_name); +int rxe_register_device (struct rxe_dev *rxe,const char *ibdev_name, +struct net_device *ndev);#endif /* RXE_VERBS_H */
include/rdma/ib_verbs.h +2 -0
@@ -4444,6 +4444,8 @@ struct net_device *ib_get_net_dev_by_par const struct sockaddr *addr);int ib_device_set_netdev (struct ib_device *ib_dev,struct net_device *ndev,unsigned int port); +struct net_device *ib_device_get_netdev (struct ib_device *ib_dev, +u32 port);struct ib_wq *ib_create_wq (struct ib_pd *pd,struct ib_wq_init_attr *init_attr);int ib_destroy_wq_user (struct ib_wq *wq,struct ib_udata *udata);
Greg Kroah-Hartman
maintainerPATCH 715/737 RDMA/rxe: Fix the failure of ibv_query_device() and ibv_query_device_ex() tests
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhu Yanjun <[email protected]>
[ Upstream commit 8ce2eb9dfac8743d1c423b86339336a5b6a6069e ]
In rdma-core, the following failures appear.
"
$ ./build/bin/run_tests.py -k device
ssssssss....FF........s
======================================================================
FAIL: test_query_device (tests.test_device.DeviceTest.test_query_device)
Test ibv_query_device()
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/ubuntu/rdma-core/tests/test_device.py", line 63, in
test_query_device
self.verify_device_attr(attr, dev)
File "/home/ubuntu/rdma-core/tests/test_device.py", line 200, in
verify_device_attr
assert attr.sys_image_guid != 0
^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError======================================================================
FAIL: test_query_device_ex (tests.test_device.DeviceTest.test_query_device_ex) Test ibv_query_device_ex()
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/ubuntu/rdma-core/tests/test_device.py", line 222, in test_query_device_ex
self.verify_device_attr(attr_ex.orig_attr, dev)
File "/home/ubuntu/rdma-core/tests/test_device.py", line 200, in verify_device_attr
assert attr.sys_image_guid != 0
^^^^^^^^^^^^^^^^^^^^^^^^AssertionError
"
The root cause is: before a net device is set with rxe, this net device is used to generate a sys_image_guid.
--- drivers/infiniband/sw/rxe/rxe.c | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-)
drivers/infiniband/sw/rxe/rxe.c +6 -19
@@ -38,10 +38,8 @@ void rxe_dealloc(struct ib_device *ib_de }/* initialize rxe device parameters */ -static void rxe_init_device_param (struct rxe_dev *rxe) +static void rxe_init_device_param (struct rxe_dev *rxe,struct net_device *ndev) { -struct net_device *ndev; - rxe->max_inline_data =RXE_MAX_INLINE_DATA ; rxe->attr.vendor_id =RXE_VENDOR_ID ;
@@ -74,15 +72,9 @@ static void rxe_init_device_param(struct rxe->attr.max_pkeys =RXE_MAX_PKEYS ; rxe->attr.local_ca_ack_delay =RXE_LOCAL_CA_ACK_DELAY ; - ndev =rxe_ib_device_get_netdev (&rxe->ib_dev); -if (!ndev) -return ; -addrconf_addr_eui48 ((unsigned char *)&rxe->attr.sys_image_guid, ndev->dev_addr); -dev_put (ndev); - rxe->max_ucontext =RXE_MAX_UCONTEXT ; }
@@ -115,18 +107,13 @@ static void rxe_init_port_param(struct r/* initialize port state, note IB convention that HCA ports are always * numbered from 1 */ -static void rxe_init_ports (struct rxe_dev *rxe) +static void rxe_init_ports (struct rxe_dev *rxe,struct net_device *ndev) {struct rxe_port *port = &rxe->port; -struct net_device *ndev;rxe_init_port_param (port); - ndev =rxe_ib_device_get_netdev (&rxe->ib_dev); -if (!ndev) -return ;addrconf_addr_eui48 ((unsigned char *)&port->port_guid, ndev->dev_addr); -dev_put (ndev);spin_lock_init (&port->port_lock); }
@@ -144,12 +131,12 @@ static void rxe_init_pools(struct rxe_de }/* initialize rxe device state */ -static void rxe_init (struct rxe_dev *rxe) +static void rxe_init (struct rxe_dev *rxe,struct net_device *ndev) {/* init default device parameters */ -rxe_init_device_param (rxe); +rxe_init_device_param (rxe, ndev); -rxe_init_ports (rxe); +rxe_init_ports (rxe, ndev);rxe_init_pools (rxe);/* init pending mmap list */
@@ -186,7 +173,7 @@ void rxe_set_mtu(struct rxe_dev *rxe, unint rxe_add (struct rxe_dev *rxe,unsigned int mtu,const char *ibdev_name,struct net_device *ndev) { -rxe_init (rxe); +rxe_init (rxe, ndev);rxe_set_mtu (rxe, mtu);return rxe_register_device (rxe, ibdev_name, ndev);
Greg Kroah-Hartman
maintainerPATCH 716/737 mm/damon/tests/vaddr-kunit: handle alloc failures on damon_test_split_evenly_succ()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit 0a63a0e7570b9b2631dfb8d836dc572709dce39e upstream.
damon_test_split_evenly_succ() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/vaddr-test.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
mm/damon/vaddr-test.h +8 -1
@@ -284,10 +284,17 @@ static void damon_test_split_evenly_succ unsigned long start, unsigned long end, unsigned int nr_pieces) { struct damon_target *t = damon_new_target(); -struct damon_region *r =damon_new_region (start, end); +struct damon_region *r;unsigned long expected_width = (end - start) / nr_pieces;unsigned long i =0 ; +if (!t) +kunit_skip (test,"target alloc fail" ); + r =damon_new_region (start, end); +if (!r) { +damon_free_target (t); +kunit_skip (test,"region alloc fail" ); + }damon_add_region (r, t);KUNIT_EXPECT_EQ (test,damon_va_evenly_split_region (t, r, nr_pieces),0 );
Greg Kroah-Hartman
maintainerPATCH 717/737 mm/damon/tests/core-kunit: handle alloc failres in damon_test_new_filter()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit 28ab2265e9422ccd81e4beafc0ace90f78de04c4 upstream.
damon_test_new_filter() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/core-test.h | 2 ++ 1 file changed, 2 insertions(+)
mm/damon/core-test.h +2 -0
@@ -346,6 +346,8 @@ static void damos_test_new_filter(structstruct damos_filter *filter; filter =damos_new_filter (DAMOS_FILTER_TYPE_ANON , true); +if (!filter) +kunit_skip (test,"filter alloc fail" );KUNIT_EXPECT_EQ (test, filter->type,DAMOS_FILTER_TYPE_ANON );KUNIT_EXPECT_EQ (test, filter->matching, true);KUNIT_EXPECT_PTR_EQ (test, filter->list.prev, &filter->list);
Greg Kroah-Hartman
maintainerPATCH 718/737 mm/damon/tests/core-kunit: handle allocation failures in damon_test_regions()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit e16fdd4f754048d6e23c56bd8d920b71e41e3777 upstream.
damon_test_regions() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/core-test.h | 6 ++++++ 1 file changed, 6 insertions(+)
mm/damon/core-test.h +6 -0
@@ -20,11 +20,17 @@ static void damon_test_regions(struct kustruct damon_target *t; r =damon_new_region (1 ,2 ); +if (!r) +kunit_skip (test,"region alloc fail" );KUNIT_EXPECT_EQ (test,1ul , r->ar.start);KUNIT_EXPECT_EQ (test,2ul , r->ar.end);KUNIT_EXPECT_EQ (test,0u , r->nr_accesses); t =damon_new_target (); +if (!t) { +damon_free_region (r); +kunit_skip (test,"target alloc fail" ); + }KUNIT_EXPECT_EQ (test,0u ,damon_nr_regions (t));damon_add_region (r, t);
Greg Kroah-Hartman
maintainerPATCH 719/737 mm/damon/tests/core-kunit: handle alloc failures on damon_test_split_at()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit 5e80d73f22043c59c8ad36452a3253937ed77955 upstream.
damon_test_split_at() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/core-test.h | 11 +++++++++++ 1 file changed, 11 insertions(+)
mm/damon/core-test.h +11 -0
@@ -129,8 +129,19 @@ static void damon_test_split_at(struct kstruct damon_target *t;struct damon_region *r; +if (!c) +kunit_skip (test,"ctx alloc fail" ); t =damon_new_target (); +if (!t) { +damon_destroy_ctx (c); +kunit_skip (test,"target alloc fail" ); + } r =damon_new_region (0 ,100 ); +if (!r) { +damon_destroy_ctx (c); +damon_free_target (t); +kunit_skip (test,"region alloc fail" ); + }damon_add_region (r, t);damon_split_region_at (t, r,25 );KUNIT_EXPECT_EQ (test, r->ar.start,0ul );
Greg Kroah-Hartman
maintainerPATCH 720/737 mm/damon/tests/core-kunit: handle alloc failures on dasmon_test_merge_regions_of()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit 0998d2757218771c59d5ca59ccf13d1542a38f17 upstream.
damon_test_merge_regions_of() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/core-test.h | 6 ++++++ 1 file changed, 6 insertions(+)
mm/damon/core-test.h +6 -0
@@ -210,8 +210,14 @@ static void damon_test_merge_regions_of(int i; t =damon_new_target (); +if (!t) +kunit_skip (test,"target alloc fail" );for (i =0 ; i <ARRAY_SIZE (sa); i++) { r =damon_new_region (sa[i], ea[i]); +if (!r) { +damon_free_target (t); +kunit_skip (test,"region alloc fail" ); + } r->nr_accesses = nrs[i];damon_add_region (r, t); }
Greg Kroah-Hartman
maintainerPATCH 721/737 mm/damon/tests/core-kunit: handle alloc failures on damon_test_merge_two()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit 3d443dd29a1db7efa587a4bb0c06a497e13ca9e4 upstream.
damon_test_merge_two() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/core-test.h | 10 ++++++++++ 1 file changed, 10 insertions(+)
mm/damon/core-test.h +10 -0
@@ -162,10 +162,20 @@ static void damon_test_merge_two(structint i; t =damon_new_target (); +if (!t) +kunit_skip (test,"target alloc fail" ); r =damon_new_region (0 ,100 ); +if (!r) { +damon_free_target (t); +kunit_skip (test,"region alloc fail" ); + } r->nr_accesses =10 ;damon_add_region (r, t); r2 =damon_new_region (100 ,300 ); +if (!r2) { +damon_free_target (t); +kunit_skip (test,"second region alloc fail" ); + } r2->nr_accesses =20 ;damon_add_region (r2, t);
Greg Kroah-Hartman
maintainerPATCH 722/737 mm/damon/tests/core-kunit: handle memory failure from damon_test_target()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit fafe953de2c661907c94055a2497c6b8dbfd26f3 upstream.
damon_test_target() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/core-test.h | 7 +++++++ 1 file changed, 7 insertions(+)
mm/damon/core-test.h +7 -0
@@ -58,7 +58,14 @@ static void damon_test_target(struct kunstruct damon_ctx *c =damon_new_ctx ();struct damon_target *t; +if (!c) +kunit_skip (test,"ctx alloc fail" ); + t =damon_new_target (); +if (!t) { +damon_destroy_ctx (c); +kunit_skip (test,"target alloc fail" ); + }KUNIT_EXPECT_EQ (test,0u ,nr_damon_targets (c));damon_add_target (c, t);
Greg Kroah-Hartman
maintainerPATCH 723/737 mm/damon/tests/core-kunit: handle alloc failures on damon_test_split_regions_of()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit eded254cb69044bd4abde87394ea44909708d7c0 upstream.
damon_test_split_regions_of() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/core-test.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
mm/damon/core-test.h +20 -0
@@ -256,15 +256,35 @@ static void damon_test_split_regions_of(struct damon_target *t;struct damon_region *r; +if (!c) +kunit_skip (test,"ctx alloc fail" ); t =damon_new_target (); +if (!t) { +damon_destroy_ctx (c); +kunit_skip (test,"target alloc fail" ); + } r =damon_new_region (0 ,22 ); +if (!r) { +damon_destroy_ctx (c); +damon_free_target (t); +kunit_skip (test,"region alloc fail" ); + }damon_add_region (r, t);damon_split_regions_of (t,2 );KUNIT_EXPECT_LE (test,damon_nr_regions (t),2u );damon_free_target (t); t =damon_new_target (); +if (!t) { +damon_destroy_ctx (c); +kunit_skip (test,"second target alloc fail" ); + } r =damon_new_region (0 ,220 ); +if (!r) { +damon_destroy_ctx (c); +damon_free_target (t); +kunit_skip (test,"second region alloc fail" ); + }damon_add_region (r, t);damon_split_regions_of (t,4 );KUNIT_EXPECT_LE (test,damon_nr_regions (t),4u );
Greg Kroah-Hartman
maintainerPATCH 724/737 mm/damon/tests/core-kunit: handle memory alloc failure from damon_test_aggregate()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit f79f2fc44ebd0ed655239046be3e80e8804b5545 upstream.
damon_test_aggregate() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/core-test.h | 11 +++++++++++ 1 file changed, 11 insertions(+)
mm/damon/core-test.h +11 -0
@@ -97,8 +97,15 @@ static void damon_test_aggregate(structstruct damon_region *r;int it, ir; +if (!ctx) +kunit_skip (test,"ctx alloc fail" ); +for (it =0 ; it <3 ; it++) { t =damon_new_target (); +if (!t) { +damon_destroy_ctx (ctx); +kunit_skip (test,"target alloc fail" ); + }damon_add_target (ctx, t); }
@@ -106,6 +113,10 @@ static void damon_test_aggregate(structdamon_for_each_target (t, ctx) {for (ir =0 ; ir <3 ; ir++) { r =damon_new_region (saddr[it][ir], eaddr[it][ir]); +if (!r) { +damon_destroy_ctx (ctx); +kunit_skip (test,"region alloc fail" ); + } r->nr_accesses = accesses[it][ir];damon_add_region (r, t); }
Greg Kroah-Hartman
maintainerPATCH 725/737 mm/damon/tests/core-kunit: handle alloc failures on damos_test_filter_out()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit d14d5671e7c9cc788c5a1edfa94e6f9064275905 upstream.
damon_test_filter_out() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/core-test.h | 11 +++++++++++ 1 file changed, 11 insertions(+)
mm/damon/core-test.h +11 -0
@@ -433,11 +433,22 @@ static void damos_test_filter_out(structstruct damos_filter *f; f =damos_new_filter (DAMOS_FILTER_TYPE_ADDR , true); +if (!f) +kunit_skip (test,"filter alloc fail" ); f->addr_range = (struct damon_addr_range ){ .start =DAMON_MIN_REGION *2 , .end =DAMON_MIN_REGION *6 }; t =damon_new_target (); +if (!t) { +damos_destroy_filter (f); +kunit_skip (test,"target alloc fail" ); + } r =damon_new_region (DAMON_MIN_REGION *3 ,DAMON_MIN_REGION *5 ); +if (!r) { +damos_destroy_filter (f); +damon_free_target (t); +kunit_skip (test,"region alloc fail" ); + }damon_add_region (r, t);/* region in the range */
Greg Kroah-Hartman
maintainerPATCH 726/737 mm/damon/tests/core-kunit: handle alloc failures in damon_test_set_regions()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit 74d5969995d129fd59dd93b9c7daa6669cb6810f upstream.
damon_test_set_regions() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/core-test.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
mm/damon/core-test.h +15 -2
@@ -341,13 +341,26 @@ static void damon_test_ops_registration(static void damon_test_set_regions (struct kunit *test) {struct damon_target *t =damon_new_target (); -struct damon_region *r1 =damon_new_region (4 ,16 ); -struct damon_region *r2 =damon_new_region (24 ,32 ); +struct damon_region *r1, *r2;struct damon_addr_range range = {.start =8 , .end =28 };unsigned long expects[] = {8 ,16 ,16 ,24 ,24 ,28 };int expect_idx =0 ;struct damon_region *r; +if (!t) +kunit_skip (test,"target alloc fail" ); + r1 =damon_new_region (4 ,16 ); +if (!r1) { +damon_free_target (t); +kunit_skip (test,"region alloc fail" ); + } + r2 =damon_new_region (24 ,32 ); +if (!r2) { +damon_free_target (t); +damon_free_region (r1); +kunit_skip (test,"second region alloc fail" ); + } +damon_add_region (r1, t);damon_add_region (r2, t);damon_set_regions (t, &range,1 );
Greg Kroah-Hartman
maintainerPATCH 727/737 mm/damon/tests/core-kunit: handle alloc failures in damon_test_ops_registration()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit 4f835f4e8c863985f15abd69db033c2f66546094 upstream.
damon_test_ops_registration() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/core-test.h | 3 +++ 1 file changed, 3 insertions(+)
mm/damon/core-test.h +3 -0
@@ -308,6 +308,9 @@ static void damon_test_ops_registration(struct damon_ctx *c =damon_new_ctx ();struct damon_operations ops, bak; +if (!c) +kunit_skip (test,"ctx alloc fail" ); +/* DAMON_OPS_{V,P}ADDR are registered on subsys_initcall */ KUNIT_EXPECT_EQ (test,damon_select_ops (c,DAMON_OPS_VADDR ),0 );KUNIT_EXPECT_EQ (test,damon_select_ops (c,DAMON_OPS_PADDR ),0 );
Greg Kroah-Hartman
maintainerPATCH 728/737 mm/damon/tests/core-kunit: handle alloc failure on damon_test_set_attrs()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit 915a2453d824a9b6bf724e3f970d86ae1d092a61 upstream.
damon_test_set_attrs() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/core-test.h | 3 +++ 1 file changed, 3 insertions(+)
mm/damon/core-test.h +3 -0
@@ -413,6 +413,9 @@ static void damon_test_set_attrs(struct .sample_interval = 5000, .aggr_interval = 100000,};struct damon_attrs invalid_attrs; +if (!c) +kunit_skip (test,"ctx alloc fail" ); +KUNIT_EXPECT_EQ (test,damon_set_attrs (c, &valid_attrs),0 ); invalid_attrs = valid_attrs;
Greg Kroah-Hartman
maintainerPATCH 729/737 mm/damon/tests/core-kunit: handle alloc failures in damon_test_update_monitoring_result()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit 8cf298c01b7fdb08eef5b6b26d0fe98d48134d72 upstream.
damon_test_update_monitoring_result() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/core-test.h | 3 +++ 1 file changed, 3 insertions(+)
mm/damon/core-test.h +3 -0
@@ -383,6 +383,9 @@ static void damon_test_update_monitoringstruct damon_attrs new_attrs;struct damon_region *r =damon_new_region (3 ,7 ); +if (!r) +kunit_skip (test,"region alloc fail" ); + r->nr_accesses =15 ; r->age =20 ;
Greg Kroah-Hartman
maintainerPATCH 730/737 virtio_console: fix order of fields cols and rows
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maximilian Immanuel Brandtner <[email protected]>
commit 5326ab737a47278dbd16ed3ee7380b26c7056ddd upstream.
According to section 5.3.6.2 (Multiport Device Operation) of the virtio spec(version 1.2) a control buffer with the event VIRTIO_CONSOLE_RESIZE is followed by a virtio_console_resize struct containing cols then rows. The kernel implements this the wrong way around (rows then cols) resulting in the two values being swapped.
Message-Id: <[email protected]>
--- drivers/char/virtio_console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/char/virtio_console.c +1 -1
@@ -1612,8 +1612,8 @@ static void handle_control_message(strucbreak ;case VIRTIO_CONSOLE_RESIZE : {struct { -__virtio16 rows;__virtio16 cols; +__virtio16 rows; } size;if (!is_console_port (port))
Greg Kroah-Hartman
maintainerPATCH 731/737 ext4: filesystems without casefold feature cannot be mounted with siphash
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lizhi Xu <[email protected]>
commit 985b67cd86392310d9e9326de941c22fc9340eec upstream.
When mounting the ext4 filesystem, if the default hash version is set to DX_HASH_SIPHASH but the casefold feature is not set, exit the mounting.
--- fs/ext4/super.c | 8 ++++++++ 1 file changed, 8 insertions(+)
fs/ext4/super.c +8 -0
@@ -3632,6 +3632,14 @@ int ext4_feature_set_ok(struct super_blo }#endif +if (EXT4_SB (sb)->s_es->s_def_hash_version ==DX_HASH_SIPHASH && + !ext4_has_feature_casefold (sb)) { +ext4_msg (sb,KERN_ERR , +"Filesystem without casefold feature cannot be " +"mounted with siphash" ); +return 0 ; + } +if (readonly)return 1 ;
Re: [PATCH 6.6 731/737] ext4: filesystems without casefold feature cannot be mounted with siphash
Hi, Greg.
The followup to 985b67cd86392310d9e9326de941c22fc9340eec, that I submitted in the same thread, has not been picked up.
[email protected]
https://lore.kernel.org/stable/[email protected]/a2187431c395 ("ext4: fix error message when rejecting the default hash")
You picked it up for 6.1 and 5.15 though.
Regards.
Cascardo.
Quoted 41 lines · Greg Kroah-Hartman
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lizhi Xu <[email protected]>
commit
985b67cd86392310d9e9326de941c22fc9340eecupstream.When mounting the ext4 filesystem, if the default hash version is set to
DX_HASH_SIPHASHbut the casefold feature is not set, exit the mounting.Reported-by [email protected]Signed-off-by Lizhi Xu <[email protected]>Signed-off-by Theodore Ts'o <[email protected]>[cascardo: small conflict fixup]Signed-off-by Thadeu Lima de Souza Cascardo <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- fs/ext4/super.c | 8 ++++++++ 1 file changed, 8 insertions(+)fs/ext4/super.c +8
-0@@ -3632,6 +3632,14 @@ int ext4_feature_set_ok(struct super_blo }#endif +if (EXT4_SB (sb)->s_es->s_def_hash_version ==DX_HASH_SIPHASH && + !ext4_has_feature_casefold (sb)) { +ext4_msg (sb,KERN_ERR , +"Filesystem without casefold feature cannot be " +"mounted with siphash" ); +return 0 ; + } +if (readonly)return 1 ;
Greg Kroah-Hartman
maintainerRe: [PATCH 6.6 731/737] ext4: filesystems without casefold feature cannot be mounted with siphash
Quoted 10 lines · Thadeu Lima de Souza Cascardo
Hi, Greg.
The followup to
985b67cd86392310d9e9326de941c22fc9340eec, that I submitted in the same thread, has not been picked up.[email protected]
https://lore.kernel.org/stable/[email protected]/a2187431c395("ext4: fix error message when rejecting the default hash")You picked it up for 6.1 and 5.15 though.
It's in the queue, odd you didn't get an email.
thanks,
greg k-h
Re: [PATCH 6.6 731/737] ext4: filesystems without casefold feature cannot be mounted with siphash
Quoted 10 lines · Greg Kroah-Hartman
Quoted 9 lines · Thadeu Lima de Souza Cascardo
Hi, Greg.
The followup to
985b67cd86392310d9e9326de941c22fc9340eec, that I submitted in the same thread, has not been picked up.[email protected]
https://lore.kernel.org/stable/[email protected]/a2187431c395("ext4: fix error message when rejecting the default hash")
Quoted 7 lines
Quoted 1 line
You picked it up for 6.1 and 5.15 though.
It's in the queue, odd you didn't get an email.
thanks,
greg k-h
Ah, I see it now, when looking for the upstream hash and not my sign-off. It was a different backport that ommitted the original fix and only applied the fixup/followup.
The original fix adds a hunk that is then removed by the followup. So when applying the followup that ignores that hunk and then the original fix with that hunk, 6.6 queue now is carrying an undesired hunk message.
If you drop a032fc761cc3f1112c42732d9a2482f23acad5fc and apply
https://lore.kernel.org/stable/[email protected]/
instead, it should be in the expected final state. I would rather do that, as then 6.6.y would be carrying the original fix, avoiding it to be backported again.
Cascardo.
Greg Kroah-Hartman
maintainerRe: [PATCH 6.6 731/737] ext4: filesystems without casefold feature cannot be mounted with siphash
Quoted 27 lines · Thadeu Lima de Souza Cascardo
Quoted 10 lines · Greg Kroah-Hartman
Quoted 9 lines · Thadeu Lima de Souza Cascardo
Hi, Greg.
The followup to
985b67cd86392310d9e9326de941c22fc9340eec, that I submitted in the same thread, has not been picked up.[email protected]
https://lore.kernel.org/stable/[email protected]/a2187431c395("ext4: fix error message when rejecting the default hash")Quoted 7 lines
Quoted 1 line
You picked it up for 6.1 and 5.15 though.
It's in the queue, odd you didn't get an email.
thanks,
greg k-h
Ah, I see it now, when looking for the upstream hash and not my sign-off. It was a different backport that ommitted the original fix and only applied the fixup/followup.
The original fix adds a hunk that is then removed by the followup. So when applying the followup that ignores that hunk and then the original fix with that hunk, 6.6 queue now is carrying an undesired hunk message.
Quoted 5 lines
If you drop
a032fc761cc3f1112c42732d9a2482f23acad5fcand apply
https://lore.kernel.org/stable/[email protected]/
instead, it should be in the expected final state. I would rather do that, as then 6.6.y would be carrying the original fix, avoiding it to be backported again.
Ok, thanks, now done!
greg k-h
Re: [PATCH 6.6 176/737] perf arm-spe: Extend branch operations
In reply to Thadeu Lima de Souza CascardoHi,
It appears that this patch broke the build, see:
In file included from util/arm-spe-decoder/arm-spe-pkt-decoder.h:10,
from util/arm-spe-decoder/arm-spe-pkt-decoder.c:14:linux/tools/include/linux/bitfield.h: In function ‘le16_encode_bits’:linux/tools/include/linux/bitfield.h:166:38: error: implicit declaration of function ‘cpu_to_le16’ [-Wimplicit-function-declaration]
166 | ____MAKE_OP(le##size,u##size,cpu_to_le##size,le##size##_to_cpu) \
| ^~~~~~~~~linux/tools/include/linux/bitfield.h:149:16: note: in definition of macro ‘____MAKE_OP’
149 | return to((v & field_mask(field)) * field_multiplier(field)); \
| ^~linux/tools/include/linux/bitfield.h:170:1: note: in expansion of macro ‘__MAKE_OP’
170 | __MAKE_OP(16)
| ^~~~~~~~~
linux/tools/include/linux/bitfield.h: In function ‘le16_get_bits’:linux/tools/include/linux/bitfield.h:166:54: error: implicit declaration of function ‘le16_to_cpu’ [-Wimplicit-function-declaration]
166 | ____MAKE_OP(le##size,u##size,cpu_to_le##size,le##size##_to_cpu) \
| ^~linux/tools/include/linux/bitfield.h:163:17: note: in definition of macro ‘____MAKE_OP’
163 | return (from(v) & field)/field_multiplier(field); \
| ^~~~linux/tools/include/linux/bitfield.h:170:1: note: in expansion of macro ‘__MAKE_OP’
170 | __MAKE_OP(16)
| ^~~~~~~~~
linux/tools/include/linux/bitfield.h: In function ‘be16_encode_bits’:linux/tools/include/linux/bitfield.h:167:38: error: implicit declaration of function ‘cpu_to_be16’ [-Wimplicit-function-declaration]
167 | ____MAKE_OP(be##size,u##size,cpu_to_be##size,be##size##_to_cpu) \
| ^~~~~~~~~linux/tools/include/linux/bitfield.h:149:16: note: in definition of macro ‘____MAKE_OP’
149 | return to((v & field_mask(field)) * field_multiplier(field)); \
| ^~linux/tools/include/linux/bitfield.h:170:1: note: in expansion of macro ‘__MAKE_OP’
170 | __MAKE_OP(16)
| ^~~~~~~~~
linux/tools/include/linux/bitfield.h: In function ‘be16_get_bits’:linux/tools/include/linux/bitfield.h:167:54: error: implicit declaration of function ‘be16_to_cpu’ [-Wimplicit-function-declaration]
167 | ____MAKE_OP(be##size,u##size,cpu_to_be##size,be##size##_to_cpu) \
| ^~linux/tools/include/linux/bitfield.h:163:17: note: in definition of macro ‘____MAKE_OP’
163 | return (from(v) & field)/field_multiplier(field); \
| ^~~~linux/tools/include/linux/bitfield.h:170:1: note: in expansion of macro ‘__MAKE_OP’
170 | __MAKE_OP(16)
| ^~~~~~~~~
linux/tools/include/linux/bitfield.h: In function ‘le32_encode_bits’:linux/tools/include/linux/bitfield.h:166:38: error: implicit declaration of function ‘cpu_to_le32’ [-Wimplicit-function-declaration]
166 | ____MAKE_OP(le##size,u##size,cpu_to_le##size,le##size##_to_cpu) \
| ^~~~~~~~~linux/tools/include/linux/bitfield.h:149:16: note: in definition of macro ‘____MAKE_OP’
149 | return to((v & field_mask(field)) * field_multiplier(field)); \
| ^~linux/tools/include/linux/bitfield.h:171:1: note: in expansion of macro ‘__MAKE_OP’
171 | __MAKE_OP(32)
| ^~~~~~~~~
linux/tools/include/linux/bitfield.h: In function ‘le32_get_bits’:linux/tools/include/linux/bitfield.h:166:54: error: implicit declaration of function ‘le32_to_cpu’ [-Wimplicit-function-declaration]
166 | ____MAKE_OP(le##size,u##size,cpu_to_le##size,le##size##_to_cpu) \
| ^~linux/tools/include/linux/bitfield.h:163:17: note: in definition of macro ‘____MAKE_OP’
163 | return (from(v) & field)/field_multiplier(field); \
| ^~~~linux/tools/include/linux/bitfield.h:171:1: note: in expansion of macro ‘__MAKE_OP’
171 | __MAKE_OP(32)
| ^~~~~~~~~
linux/tools/include/linux/bitfield.h: In function ‘be32_encode_bits’:linux/tools/include/linux/bitfield.h:167:38: error: implicit declaration of function ‘cpu_to_be32’ [-Wimplicit-function-declaration]
167 | ____MAKE_OP(be##size,u##size,cpu_to_be##size,be##size##_to_cpu) \
| ^~~~~~~~~linux/tools/include/linux/bitfield.h:149:16: note: in definition of macro ‘____MAKE_OP’
149 | return to((v & field_mask(field)) * field_multiplier(field)); \
| ^~linux/tools/include/linux/bitfield.h:171:1: note: in expansion of macro ‘__MAKE_OP’
171 | __MAKE_OP(32)
| ^~~~~~~~~
linux/tools/include/linux/bitfield.h: In function ‘be32_get_bits’:linux/tools/include/linux/bitfield.h:167:54: error: implicit declaration of function ‘be32_to_cpu’ [-Wimplicit-function-declaration]
167 | ____MAKE_OP(be##size,u##size,cpu_to_be##size,be##size##_to_cpu) \
| ^~linux/tools/include/linux/bitfield.h:163:17: note: in definition of macro ‘____MAKE_OP’
163 | return (from(v) & field)/field_multiplier(field); \
| ^~~~linux/tools/include/linux/bitfield.h:171:1: note: in expansion of macro ‘__MAKE_OP’
171 | __MAKE_OP(32)
| ^~~~~~~~~
CC util/thread.olinux/tools/include/linux/bitfield.h: In function ‘le64_encode_bits’:linux/tools/include/linux/bitfield.h:166:38: error: implicit declaration of function ‘cpu_to_le64’ [-Wimplicit-function-declaration]
166 | ____MAKE_OP(le##size,u##size,cpu_to_le##size,le##size##_to_cpu) \
| ^~~~~~~~~linux/tools/include/linux/bitfield.h:149:16: note: in definition of macro ‘____MAKE_OP’
149 | return to((v & field_mask(field)) * field_multiplier(field)); \
| ^~linux/tools/include/linux/bitfield.h:172:1: note: in expansion of macro ‘__MAKE_OP’
172 | __MAKE_OP(64)
| ^~~~~~~~~
linux/tools/include/linux/bitfield.h: In function ‘le64_get_bits’:linux/tools/include/linux/bitfield.h:166:54: error: implicit declaration of function ‘le64_to_cpu’ [-Wimplicit-function-declaration]
166 | ____MAKE_OP(le##size,u##size,cpu_to_le##size,le##size##_to_cpu) \
| ^~linux/tools/include/linux/bitfield.h:163:17: note: in definition of macro ‘____MAKE_OP’
163 | return (from(v) & field)/field_multiplier(field); \
| ^~~~linux/tools/include/linux/bitfield.h:172:1: note: in expansion of macro ‘__MAKE_OP’
172 | __MAKE_OP(64)
| ^~~~~~~~~
linux/tools/include/linux/bitfield.h: In function ‘be64_encode_bits’:
CC util/thread_map.olinux/tools/include/linux/bitfield.h:167:38: error: implicit declaration of function ‘cpu_to_be64’ [-Wimplicit-function-declaration]
167 | ____MAKE_OP(be##size,u##size,cpu_to_be##size,be##size##_to_cpu) \
| ^~~~~~~~~linux/tools/include/linux/bitfield.h:149:16: note: in definition of macro ‘____MAKE_OP’
149 | return to((v & field_mask(field)) * field_multiplier(field)); \
| ^~linux/tools/include/linux/bitfield.h:172:1: note: in expansion of macro ‘__MAKE_OP’
172 | __MAKE_OP(64)
| ^~~~~~~~~
linux/tools/include/linux/bitfield.h: In function ‘be64_get_bits’:linux/tools/include/linux/bitfield.h:167:54: error: implicit declaration of function ‘be64_to_cpu’ [-Wimplicit-function-declaration]
167 | ____MAKE_OP(be##size,u##size,cpu_to_be##size,be##size##_to_cpu) \
| ^~linux/tools/include/linux/bitfield.h:163:17: note: in definition of macro ‘____MAKE_OP’
163 | return (from(v) & field)/field_multiplier(field); \
| ^~~~linux/tools/include/linux/bitfield.h:172:1: note: in expansion of macro ‘__MAKE_OP’
172 | __MAKE_OP(64)
| ^~~~~~~~~
BR,
Hamza
Re: [PATCH 6.6 176/737] perf arm-spe: Extend branch operations
I replied to the wrong thread, please disregard this message.
Greg Kroah-Hartman
maintainerPATCH 732/737 net: stmmac: make sure that ptp_rate is not 0 before configuring EST
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexis Lothoré <[email protected]>
commit cbefe2ffa7784525ec5d008ba87c7add19ec631a upstream.
If the ptp_rate recorded earlier in the driver happens to be 0, this bogus value will propagate up to EST configuration, where it will trigger a division by 0.
Prevent this division by 0 by adding the corresponding check and error code.
[ The context change is due to the commit c3f3b97238f6
("net: stmmac: Refactor EST implementation") which is irrelevant to the logic of this patch. ]
--- drivers/net/ethernet/stmicro/stmmac/dwmac5.c | 5 +++++ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 5 +++++ 2 files changed, 10 insertions(+)
drivers/net/ethernet/stmicro/stmmac/dwmac5.c +5 -0
@@ -597,6 +597,11 @@ int dwmac5_est_configure(void __iomem *iint i, ret =0x0 ;u32 ctrl; +if (!ptp_rate) { +pr_warn ("Dwmac5: Invalid PTP rate" ); +return -EINVAL ; + } + ret |=dwmac5_est_write (ioaddr,BTR_LOW , cfg->btr[0 ], false); ret |=dwmac5_est_write (ioaddr,BTR_HIGH , cfg->btr[1 ], false); ret |=dwmac5_est_write (ioaddr,TER , cfg->ter, false);
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c +5 -0
@@ -1537,6 +1537,11 @@ static int dwxgmac3_est_configure(void _int i, ret =0x0 ;u32 ctrl; +if (!ptp_rate) { +pr_warn ("Dwxgmac2: Invalid PTP rate" ); +return -EINVAL ; + } + ret |=dwxgmac3_est_write (ioaddr,XGMAC_BTR_LOW , cfg->btr[0 ], false); ret |=dwxgmac3_est_write (ioaddr,XGMAC_BTR_HIGH , cfg->btr[1 ], false); ret |=dwxgmac3_est_write (ioaddr,XGMAC_TER , cfg->ter, false);
Greg Kroah-Hartman
maintainerPATCH 733/737 pwm: stm32: Always program polarity
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Nyekjaer <[email protected]>
Commit 7346e7a058a2 ("pwm: stm32: Always do lazy disabling") triggered a regression where PWM polarity changes could be ignored.
stm32_pwm_set_polarity() was skipped due to a mismatch between the cached pwm->state.polarity and the actual hardware state, leaving the hardware polarity unchanged.
--- drivers/pwm/pwm-stm32.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/pwm/pwm-stm32.c +1 -2
@@ -462,8 +462,7 @@ static int stm32_pwm_apply(struct pwm_chreturn 0 ; } -if (state->polarity != pwm->state.polarity) -stm32_pwm_set_polarity (priv, pwm->hwpwm, state->polarity); +stm32_pwm_set_polarity (priv, pwm->hwpwm, state->polarity); ret =stm32_pwm_config (priv, pwm->hwpwm, state->duty_cycle, state->period);
Greg Kroah-Hartman
maintainerPATCH 734/737 blk-mq: setup queue ->tag_set before initializing hctx
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Lei <[email protected]>
commit c25c0c9035bb8b28c844dfddeda7b8bdbcfcae95 upstream.
Commit 7b815817aa58 ("blk-mq: add helper for checking if one CPU is mapped to specified hctx") needs to check queue mapping via tag set in hctx's cpuhp handler.
However, q->tag_set may not be setup yet when the cpuhp handler is enabled, then kernel oops is triggered.
Fix the issue by setup queue tag_set before initializing hctx.
--- block/blk-mq.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
block/blk-mq.c +6 -2
@@ -4453,6 +4453,12 @@ int blk_mq_init_allocated_queue(struct b/* mark the queue as mq asap */ q->mq_ops = set->ops; +/* +* ->tag_set has to be setup before initialize hctx, which cpuphp +* handler needs it for checking queue mapping +*/ + q->tag_set = set; +if (blk_mq_alloc_ctxs (q)) goto err_exit;
@@ -4471,8 +4477,6 @@ int blk_mq_init_allocated_queue(struct bINIT_WORK (&q->timeout_work, blk_mq_timeout_work);blk_queue_rq_timeout (q, set->timeout ? set->timeout :30 *HZ ); - q->tag_set = set; - q->queue_flags |=QUEUE_FLAG_MQ_DEFAULT ;blk_mq_update_poll_flag (q);
Greg Kroah-Hartman
maintainerPATCH 735/737 tty: fix tty_port_tty_*hangup() kernel-doc
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Slaby (SUSE) <[email protected]>
commit 6241b49540a65a6d5274fa938fd3eb4cbfe2e076 upstream.
The commit below added a new helper, but omitted to move (and add) the corressponding kernel-doc. Do it now.
--- Documentation/driver-api/tty/tty_port.rst | 5 +++-- drivers/tty/tty_port.c | 5 ----- include/linux/tty_port.h | 9 +++++++++ 3 files changed, 12 insertions(+), 7 deletions(-)
Documentation/driver-api/tty/tty_port.rst +3 -2
@@ -42,9 +42,10 @@ TTY Refcounting TTY Helpers ----------- +.. kernel-doc:: include/linux/tty_port.h + :identifiers: tty_port_tty_hangup tty_port_tty_vhangup .. kernel-doc:: drivers/tty/tty_port.c - :identifiers: tty_port_tty_hangup tty_port_tty_wakeup - + :identifiers: tty_port_tty_wakeup Modem Signals -------------
drivers/tty/tty_port.c +0 -5
@@ -409,11 +409,6 @@ void tty_port_hangup(struct tty_port *po }EXPORT_SYMBOL (tty_port_hangup); -/** -* tty_port_tty_hangup - helper to hang up a tty -* @port: tty port -* @check_clocal: hang only ttys with %CLOCAL unset? -*/ void __tty_port_tty_hangup (struct tty_port *port,bool check_clocal,bool async) {struct tty_struct *tty =tty_port_tty_get (port);
include/linux/tty_port.h +9 -0
@@ -254,11 +254,20 @@ static inline int tty_port_users(structreturn port->count + port->blocked_open; } +/** +* tty_port_tty_hangup - helper to hang up a tty asynchronously +* @port: tty port +* @check_clocal: hang only ttys with %CLOCAL unset? +*/ static inline void tty_port_tty_hangup (struct tty_port *port,bool check_clocal) {__tty_port_tty_hangup (port, check_clocal, true); } +/** +* tty_port_tty_vhangup - helper to hang up a tty synchronously +* @port: tty port +*/ static inline void tty_port_tty_vhangup (struct tty_port *port) {__tty_port_tty_hangup (port, false, false);
Greg Kroah-Hartman
maintainerPATCH 736/737 firmware: arm_scmi: Fix unused notifier-block in unregister
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amitai Gottlieb <[email protected]>
In scmi_devm_notifier_unregister(), the notifier-block argument was ignored and never passed to devres_release(). As a result, the function always returned -ENOENT and failed to unregister the notifier.
Drivers that depend on this helper for teardown could therefore hit unexpected failures, including kernel panics.
Commit 264a2c520628 ("firmware: arm_scmi: Simplify scmi_devm_notifier_unregister") removed the faulty code path during refactoring and hence this fix is not required upstream.
--- drivers/firmware/arm_scmi/notify.c | 1 + 1 file changed, 1 insertion(+)
drivers/firmware/arm_scmi/notify.c +1 -0
@@ -1539,6 +1539,7 @@ static int scmi_devm_notifier_unregister dres.handle = sdev->handle; dres.proto_id = proto_id; dres.evt_id = evt_id; + dres.nb = nb;if (src_id) { dres.__src_id = *src_id; dres.src_id = &dres.__src_id;
Greg Kroah-Hartman
maintainerPATCH 737/737 Revert "iommu/amd: Skip enabling command/event buffers for kdump"
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Greg Kroah-Hartman <[email protected]>
This reverts commit 44a764aec64b3f3235b9cbac2525222f69685418 which is commit 9be15fbfc6c5c89c22cf6e209f66ea43ee0e58bb upstream.
This causes problems in older kernel trees as SNP host kdump is not supported in them, so drop it from the stable branches.
--- drivers/iommu/amd/init.c | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-)
drivers/iommu/amd/init.c +9 -19
@@ -840,16 +840,11 @@ static void iommu_enable_command_buffer(BUG_ON (iommu->cmd_buf ==NULL ); -if (!is_kdump_kernel ()) { -/* -* Command buffer is re-used for kdump kernel and setting -* of MMIO register is not required. -*/ - entry =iommu_virt_to_phys (iommu->cmd_buf); - entry |=MMIO_CMD_SIZE_512 ; -memcpy_toio (iommu->mmio_base +MMIO_CMD_BUF_OFFSET , - &entry,sizeof (entry)); - } + entry =iommu_virt_to_phys (iommu->cmd_buf); + entry |=MMIO_CMD_SIZE_512 ; + +memcpy_toio (iommu->mmio_base +MMIO_CMD_BUF_OFFSET , + &entry,sizeof (entry));amd_iommu_reset_cmd_buffer (iommu); }
@@ -898,15 +893,10 @@ static void iommu_enable_event_buffer(stBUG_ON (iommu->evt_buf ==NULL ); -if (!is_kdump_kernel ()) { -/* -* Event buffer is re-used for kdump kernel and setting -* of MMIO register is not required. -*/ - entry =iommu_virt_to_phys (iommu->evt_buf) |EVT_LEN_MASK ; -memcpy_toio (iommu->mmio_base +MMIO_EVT_BUF_OFFSET , - &entry,sizeof (entry)); - } + entry =iommu_virt_to_phys (iommu->evt_buf) |EVT_LEN_MASK ; + +memcpy_toio (iommu->mmio_base +MMIO_EVT_BUF_OFFSET , + &entry,sizeof (entry));/* set head and tail to zero manually */ writel (0x00 , iommu->mmio_base +MMIO_EVT_HEAD_OFFSET );
# Librecast Test Results
020/020 [ OK ] liblcrq
010/010 [ OK ] libmld
120/120 [ OK ] liblibrecast
CPU/kernel: Linux auntie 6.6.120-rc1-g00f48cae9e13 #1 SMP PREEMPT_DYNAMIC Fri Jan 9 18:23:00 -00 2026 x86_64 AMD Ryzen 9 9950X 16-Core Processor AuthenticAMD GNU/Linux
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.120 release. There are 737 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 11 Jan 2026 11:19:41 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.120-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Signature · 1 line
Florian
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.120 release. There are 737 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 11 Jan 2026 11:19:41 +0000. Anything received after that time might be too late.
6.6.120-rc1 built and run on my x86_64 test system (AMD Ryzen 9 9900X, System76 thelio-mira-r4-n3). No errors or regressions.
Thanks,
Slade
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.120 release. There are 737 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 11 Jan 2026 11:19:41 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.120-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Am 09.01.2026 um 12:32 schrieb Greg Kroah-Hartman:
Quoted 4 lines
This is the start of the stable review cycle for the 6.6.120 release. There are 737 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Builds, boots and works on my 2-socket Ivy Bridge Xeon E5-2697 v2 server. No dmesg oddities or regressions found.
Beste Grüße,
Peter Schneider
Signature · 8 lines
Climb the mountain not to plant your flag, but to embrace the challenge, enjoy the air and behold the view. Climb it so you can see the world, not so the world can see you. -- David McCullough Jr. OpenPGP: 0xA3828BD796CCE11A8CADE8866E3A92C92C3FF244 Download: https://www.peters-netzplatz.de/download/pschneider1968_pub.asc https://keys.mailvelope.com/pks/lookup?op=get&[email protected] https://keys.mailvelope.com/pks/lookup?op=get&[email protected]
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.120 release. There are 737 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 11 Jan 2026 11:19:41 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.120-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.120 release. There are 737 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Compiled and tested on
- Verdin iMX8MM
- Colibri iMX6
- Apalis iMX6
- Colibri iMX6ULL
- Colibri iMX7
hello
Compiled and booted 6.6.120-rc1+
No typical new regressions from dmesg.
As per dmidecode command.
Version: AMD Ryzen 3 3250U with Radeon Graphics
Processor Information
Socket Designation: FP5
Type: Central Processor
Family: Zen
Manufacturer: Advanced Micro Devices, Inc.
ID: 81 0F 81 00 FF FB 8B 17
Signature: Family 23, Model 24, Stepping 1
--
software engineer
rajagiri school of engineering and technology
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.120 release. There are 737 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 11 Jan 2026 11:19:41 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.120-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v6.6:
10 builds: 10 pass, 0 fail
28 boots: 28 pass, 0 fail
120 tests: 120 pass, 0 failLinux version: 6.6.120-rc1-g00f48cae9e13
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra186-p3509-0000+p3636-0001, tegra194-p2972-0000,
tegra194-p3509-0000+p3668-0000, tegra20-ventana,
tegra210-p2371-2180, tegra210-p3450-0000,
tegra30-cardhu-a04Jon
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.120 release. There are 737 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 8 lines · On Fri, 09 Jan 2026 12:32:19 +0100 Greg Kroah-Hartman…
This is the start of the stable review cycle for the 6.6.120 release. There are 737 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 11 Jan 2026 11:19:41 +0000. Anything received after that time might be too late.
Boot-tested under QEMU for Rust x86_64:
Thanks!
Cheers,
Miguel