6.1.23-rc1 review
Subsystems (3)
Greg Kroah-Hartman
maintainerPATCH 130/181 btrfs: fix deadlock when aborting transaction during relocation with scrub
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
commit 2d82a40aa7d6fcae0250ec68b8566cdee7bfd44c upstream.
Before relocating a block group we pause scrub, then do the relocation and then unpause scrub. The relocation process requires starting and committing a transaction, and if we have a failure in the critical section of the transaction commit path (transaction state >= TRANS_STATE_COMMIT_START), we will deadlock if there is a paused scrub.
That results in stack traces like the following:
[42.479] BTRFS info (device sdc): relocating block group 53876686848 flags metadata|raid6 [42.936] BTRFS warning (device sdc): Skipping commit of aborted transaction. [42.936] ------------[ cut here ]------------ [42.936] BTRFS: Transaction aborted (error -28) [42.936] WARNING: CPU: 11 PID: 346822 at fs/btrfs/transaction.c:1977 btrfs_commit_transaction+0xcc8/0xeb0 [btrfs] [42.936] Modules linked in: dm_flakey dm_mod loop btrfs (...) [42.936] CPU: 11 PID: 346822 Comm: btrfs Tainted: G W 6.3.0-rc2-btrfs-next-127+ #1 [42.936] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014 [42.936] RIP: 0010:btrfs_commit_transaction+0xcc8/0xeb0 [btrfs] [42.936] Code: ff ff 45 8b (...) [42.936] RSP: 0018:ffffb58649633b48 EFLAGS: 00010282 [42.936] RAX: 0000000000000000 RBX: ffff8be6ef4d5bd8 RCX: 0000000000000000 [42.936] RDX: 0000000000000002 RSI: ffffffffb35e7782 RDI: 00000000ffffffff [42.936] RBP: ffff8be6ef4d5c98 R08: 0000000000000000 R09: ffffb586496339e8 [42.936] R10: 0000000000000001 R11: 0000000000000001 R12: ffff8be6d38c7c00 [42.936] R13: 00000000ffffffe4 R14: ffff8be6c268c000 R15: ffff8be6ef4d5cf0 [42.936] FS: 00007f381a82b340(0000) GS:ffff8beddfcc0000(0000) knlGS:0000000000000000 [42.936] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [42.936] CR2: 00007f1e35fb7638 CR3: 0000000117680006 CR4: 0000000000370ee0 [42.936] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [42.936] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [42.936] Call Trace: [42.936] <TASK> [42.936] ? start_transaction+0xcb/0x610 [btrfs] [42.936] prepare_to_relocate+0x111/0x1a0 [btrfs] [42.936] relocate_block_group+0x57/0x5d0 [btrfs] [42.936] ? btrfs_wait_nocow_writers+0x25/0xb0 [btrfs] [42.936] btrfs_relocate_block_group+0x248/0x3c0 [btrfs] [42.936] ? __pfx_autoremove_wake_function+0x10/0x10 [42.936] btrfs_relocate_chunk+0x3b/0x150 [btrfs] [42.936] btrfs_balance+0x8ff/0x11d0 [btrfs] [42.936] ? __kmem_cache_alloc_node+0x14a/0x410 [42.936] btrfs_ioctl+0x2334/0x32c0 [btrfs] [42.937] ? mod_objcg_state+0xd2/0x360 [42.937] ? refill_obj_stock+0xb0/0x160 [42.937] ? seq_release+0x25/0x30 [42.937] ? __rseq_handle_notify_resume+0x3b5/0x4b0 [42.937] ? percpu_counter_add_batch+0x2e/0xa0 [42.937] ? __x64_sys_ioctl+0x88/0xc0 [42.937] __x64_sys_ioctl+0x88/0xc0 [42.937] do_syscall_64+0x38/0x90 [42.937] entry_SYSCALL_64_after_hwframe+0x72/0xdc [42.937] RIP: 0033:0x7f381a6ffe9b [42.937] Code: 00 48 89 44 24 (...) [42.937] RSP: 002b:00007ffd45ecf060 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [42.937] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f381a6ffe9b [42.937] RDX: 00007ffd45ecf150 RSI: 00000000c4009420 RDI: 0000000000000003 [42.937] RBP: 0000000000000003 R08: 0000000000000013 R09: 0000000000000000 [42.937] R10: 00007f381a60c878 R11: 0000000000000246 R12: 00007ffd45ed0423 [42.937] R13: 00007ffd45ecf150 R14: 0000000000000000 R15: 00007ffd45ecf148 [42.937] </TASK> [42.937] ---[ end trace 0000000000000000 ]--- [42.937] BTRFS: error (device sdc: state A) in cleanup_transaction:1977: errno=-28 No space left [59.196] INFO: task btrfs:346772 blocked for more than 120 seconds. [59.196] Tainted: G W 6.3.0-rc2-btrfs-next-127+ #1 [59.196] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [59.196] task:btrfs state:D stack:0 pid:346772 ppid:1 flags:0x00004002 [59.196] Call Trace: [59.196] <TASK> [59.196] __schedule+0x392/0xa70 [59.196] ? __pv_queued_spin_lock_slowpath+0x165/0x370 [59.196] schedule+0x5d/0xd0 [59.196] __scrub_blocked_if_needed+0x74/0xc0 [btrfs] [59.197] ? __pfx_autoremove_wake_function+0x10/0x10 [59.197] scrub_pause_off+0x21/0x50 [btrfs] [59.197] scrub_simple_mirror+0x1c7/0x950 [btrfs] [59.197] ? scrub_parity_put+0x1a5/0x1d0 [btrfs] [59.198] ? __pfx_autoremove_wake_function+0x10/0x10 [59.198] scrub_stripe+0x20d/0x740 [btrfs] [59.198] scrub_chunk+0xc4/0x130 [btrfs] [59.198] scrub_enumerate_chunks+0x3e4/0x7a0 [btrfs] [59.198] ? __pfx_autoremove_wake_function+0x10/0x10 [59.198] btrfs_scrub_dev+0x236/0x6a0 [btrfs] [59.199] ? btrfs_ioctl+0xd97/0x32c0 [btrfs] [59.199] ? _copy_from_user+0x7b/0x80 [59.199] btrfs_ioctl+0xde1/0x32c0 [btrfs] [59.199] ? refill_stock+0x33/0x50 [59.199] ? should_failslab+0xa/0x20 [59.199] ? kmem_cache_alloc_node+0x151/0x460 [59.199] ? alloc_io_context+0x1b/0x80 [59.199] ? preempt_count_add+0x70/0xa0 [59.199] ? __x64_sys_ioctl+0x88/0xc0 [59.199] __x64_sys_ioctl+0x88/0xc0 [59.199] do_syscall_64+0x38/0x90 [59.199] entry_SYSCALL_64_after_hwframe+0x72/0xdc [59.199] RIP: 0033:0x7f82ffaffe9b [59.199] RSP: 002b:00007f82ff9fcc50 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [59.199] RAX: ffffffffffffffda RBX: 000055b191e36310 RCX: 00007f82ffaffe9b [59.199] RDX: 000055b191e36310 RSI: 00000000c400941b RDI: 0000000000000003 [59.199] RBP: 0000000000000000 R08: 00007fff1575016f R09: 0000000000000000 [59.199] R10: 0000000000000000 R11: 0000000000000246 R12: 00007f82ff9fd640 [59.199] R13: 000000000000006b R14: 00007f82ffa87580 R15: 0000000000000000 [59.199] </TASK> [59.199] INFO: task btrfs:346773 blocked for more than 120 seconds. [59.200] Tainted: G W 6.3.0-rc2-btrfs-next-127+ #1 [59.200] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [59.201] task:btrfs state:D stack:0 pid:346773 ppid:1 flags:0x00004002 [59.201] Call Trace: [59.201] <TASK> [59.201] __schedule+0x392/0xa70 [59.201] ? __pv_queued_spin_lock_slowpath+0x165/0x370 [59.201] schedule+0x5d/0xd0 [59.201] __scrub_blocked_if_needed+0x74/0xc0 [btrfs] [59.201] ? __pfx_autoremove_wake_function+0x10/0x10 [59.201] scrub_pause_off+0x21/0x50 [btrfs] [59.202] scrub_simple_mirror+0x1c7/0x950 [btrfs] [59.202] ? scrub_parity_put+0x1a5/0x1d0 [btrfs] [59.202] ? __pfx_autoremove_wake_function+0x10/0x10 [59.202] scrub_stripe+0x20d/0x740 [btrfs] [59.202] scrub_chunk+0xc4/0x130 [btrfs] [59.203] scrub_enumerate_chunks+0x3e4/0x7a0 [btrfs] [59.203] ? __pfx_autoremove_wake_function+0x10/0x10 [59.203] btrfs_scrub_dev+0x236/0x6a0 [btrfs] [59.203] ? btrfs_ioctl+0xd97/0x32c0 [btrfs] [59.203] ? _copy_from_user+0x7b/0x80 [59.203] btrfs_ioctl+0xde1/0x32c0 [btrfs] [59.204] ? should_failslab+0xa/0x20 [59.204] ? kmem_cache_alloc_node+0x151/0x460 [59.204] ? alloc_io_context+0x1b/0x80 [59.204] ? preempt_count_add+0x70/0xa0 [59.204] ? __x64_sys_ioctl+0x88/0xc0 [59.204] __x64_sys_ioctl+0x88/0xc0 [59.204] do_syscall_64+0x38/0x90 [59.204] entry_SYSCALL_64_after_hwframe+0x72/0xdc [59.204] RIP: 0033:0x7f82ffaffe9b [59.204] RSP: 002b:00007f82ff1fbc50 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [59.204] RAX: ffffffffffffffda RBX: 000055b191e36790 RCX: 00007f82ffaffe9b [59.204] RDX: 000055b191e36790 RSI: 00000000c400941b RDI: 0000000000000003 [59.204] RBP: 0000000000000000 R08: 00007fff1575016f R09: 0000000000000000 [59.204] R10: 0000000000000000 R11: 0000000000000246 R12: 00007f82ff1fc640 [59.204] R13: 000000000000006b R14: 00007f82ffa87580 R15: 0000000000000000 [59.204] </TASK> [59.204] INFO: task btrfs:346774 blocked for more than 120 seconds. [59.205] Tainted: G W 6.3.0-rc2-btrfs-next-127+ #1 [59.205] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [59.206] task:btrfs state:D stack:0 pid:346774 ppid:1 flags:0x00004002 [59.206] Call Trace: [59.206] <TASK> [59.206] __schedule+0x392/0xa70 [59.206] schedule+0x5d/0xd0 [59.206] __scrub_blocked_if_needed+0x74/0xc0 [btrfs] [59.206] ? __pfx_autoremove_wake_function+0x10/0x10 [59.206] scrub_pause_off+0x21/0x50 [btrfs] [59.207] scrub_simple_mirror+0x1c7/0x950 [btrfs] [59.207] ? scrub_parity_put+0x1a5/0x1d0 [btrfs] [59.207] ? __pfx_autoremove_wake_function+0x10/0x10 [59.207] scrub_stripe+0x20d/0x740 [btrfs] [59.208] scrub_chunk+0xc4/0x130 [btrfs] [59.208] scrub_enumerate_chunks+0x3e4/0x7a0 [btrfs] [59.208] ? __mutex_unlock_slowpath.isra.0+0x9a/0x120 [59.208] btrfs_scrub_dev+0x236/0x6a0 [btrfs] [59.208] ? btrfs_ioctl+0xd97/0x32c0 [btrfs] [59.209] ? _copy_from_user+0x7b/0x80 [59.209] btrfs_ioctl+0xde1/0x32c0 [btrfs] [59.209] ? should_failslab+0xa/0x20 [59.209] ? kmem_cache_alloc_node+0x151/0x460 [59.209] ? alloc_io_context+0x1b/0x80 [59.209] ? preempt_count_add+0x70/0xa0 [59.209] ? __x64_sys_ioctl+0x88/0xc0 [59.209] __x64_sys_ioctl+0x88/0xc0 [59.209] do_syscall_64+0x38/0x90 [59.209] entry_SYSCALL_64_after_hwframe+0x72/0xdc [59.209] RIP: 0033:0x7f82ffaffe9b [59.209] RSP: 002b:00007f82fe9fac50 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [59.209] RAX: ffffffffffffffda RBX: 000055b191e36c10 RCX: 00007f82ffaffe9b [59.209] RDX: 000055b191e36c10 RSI: 00000000c400941b RDI: 0000000000000003 [59.209] RBP: 0000000000000000 R08: 00007fff1575016f R09: 0000000000000000 [59.209] R10: 0000000000000000 R11: 0000000000000246 R12: 00007f82fe9fb640 [59.209] R13: 000000000000006b R14: 00007f82ffa87580 R15: 0000000000000000 [59.209] </TASK> [59.209] INFO: task btrfs:346775 blocked for more than 120 seconds. [59.210] Tainted: G W 6.3.0-rc2-btrfs-next-127+ #1 [59.210] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [59.211] task:btrfs state:D stack:0 pid:346775 ppid:1 flags:0x00004002 [59.211] Call Trace: [59.211] <TASK> [59.211] __schedule+0x392/0xa70 [59.211] schedule+0x5d/0xd0 [59.211] __scrub_blocked_if_needed+0x74/0xc0 [btrfs] [59.211] ? __pfx_autoremove_wake_function+0x10/0x10 [59.211] scrub_pause_off+0x21/0x50 [btrfs] [59.212] scrub_simple_mirror+0x1c7/0x950 [btrfs] [59.212] ? scrub_parity_put+0x1a5/0x1d0 [btrfs] [59.212] ? __pfx_autoremove_wake_function+0x10/0x10 [59.212] scrub_stripe+0x20d/0x740 [btrfs] [59.213] scrub_chunk+0xc4/0x130 [btrfs] [59.213] scrub_enumerate_chunks+0x3e4/0x7a0 [btrfs] [59.213] ? __mutex_unlock_slowpath.isra.0+0x9a/0x120 [59.213] btrfs_scrub_dev+0x236/0x6a0 [btrfs] [59.213] ? btrfs_ioctl+0xd97/0x32c0 [btrfs] [59.214] ? _copy_from_user+0x7b/0x80 [59.214] btrfs_ioctl+0xde1/0x32c0 [btrfs] [59.214] ? should_failslab+0xa/0x20 [59.214] ? kmem_cache_alloc_node+0x151/0x460 [59.214] ? alloc_io_context+0x1b/0x80 [59.214] ? preempt_count_add+0x70/0xa0 [59.214] ? __x64_sys_ioctl+0x88/0xc0 [59.214] __x64_sys_ioctl+0x88/0xc0 [59.214] do_syscall_64+0x38/0x90 [59.214] entry_SYSCALL_64_after_hwframe+0x72/0xdc [59.214] RIP: 0033:0x7f82ffaffe9b [59.214] RSP: 002b:00007f82fe1f9c50 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [59.214] RAX: ffffffffffffffda RBX: 000055b191e37090 RCX: 00007f82ffaffe9b [59.214] RDX: 000055b191e37090 RSI: 00000000c400941b RDI: 0000000000000003 [59.214] RBP: 0000000000000000 R08: 00007fff1575016f R09: 0000000000000000 [59.214] R10: 0000000000000000 R11: 0000000000000246 R12: 00007f82fe1fa640 [59.214] R13: 000000000000006b R14: 00007f82ffa87580 R15: 0000000000000000 [59.214] </TASK> [59.214] INFO: task btrfs:346776 blocked for more than 120 seconds. [59.215] Tainted: G W 6.3.0-rc2-btrfs-next-127+ #1 [59.216] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [59.217] task:btrfs state:D stack:0 pid:346776 ppid:1 flags:0x00004002 [59.217] Call Trace: [59.217] <TASK> [59.217] __schedule+0x392/0xa70 [59.217] ? __pv_queued_spin_lock_slowpath+0x165/0x370 [59.217] schedule+0x5d/0xd0 [59.217] __scrub_blocked_if_needed+0x74/0xc0 [btrfs] [59.217] ? __pfx_autoremove_wake_function+0x10/0x10 [59.217] scrub_pause_off+0x21/0x50 [btrfs] [59.217] scrub_simple_mirror+0x1c7/0x950 [btrfs] [59.217] ? scrub_parity_put+0x1a5/0x1d0 [btrfs] [59.218] ? __pfx_autoremove_wake_function+0x10/0x10 [59.218] scrub_stripe+0x20d/0x740 [btrfs] [59.218] scrub_chunk+0xc4/0x130 [btrfs] [59.218] scrub_enumerate_chunks+0x3e4/0x7a0 [btrfs] [59.219] ? __pfx_autoremove_wake_function+0x10/0x10 [59.219] btrfs_scrub_dev+0x236/0x6a0 [btrfs] [59.219] ? btrfs_ioctl+0xd97/0x32c0 [btrfs] [59.219] ? _copy_from_user+0x7b/0x80 [59.219] btrfs_ioctl+0xde1/0x32c0 [btrfs] [59.219] ? should_failslab+0xa/0x20 [59.219] ? kmem_cache_alloc_node+0x151/0x460 [59.219] ? alloc_io_context+0x1b/0x80 [59.219] ? preempt_count_add+0x70/0xa0 [59.219] ? __x64_sys_ioctl+0x88/0xc0 [59.219] __x64_sys_ioctl+0x88/0xc0 [59.219] do_syscall_64+0x38/0x90 [59.219] entry_SYSCALL_64_after_hwframe+0x72/0xdc [59.219] RIP: 0033:0x7f82ffaffe9b [59.219] RSP: 002b:00007f82fd9f8c50 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [59.219] RAX: ffffffffffffffda RBX: 000055b191e37510 RCX: 00007f82ffaffe9b [59.219] RDX: 000055b191e37510 RSI: 00000000c400941b RDI: 0000000000000003 [59.219] RBP: 0000000000000000 R08: 00007fff1575016f R09: 0000000000000000 [59.219] R10: 0000000000000000 R11: 0000000000000246 R12: 00007f82fd9f9640 [59.219] R13: 000000000000006b R14: 00007f82ffa87580 R15: 0000000000000000 [59.219] </TASK> [59.219] INFO: task btrfs:346822 blocked for more than 120 seconds. [59.220] Tainted: G W 6.3.0-rc2-btrfs-next-127+ #1 [59.221] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [59.222] task:btrfs state:D stack:0 pid:346822 ppid:1 flags:0x00004002 [59.222] Call Trace: [59.222] <TASK> [59.222] __schedule+0x392/0xa70 [59.222] schedule+0x5d/0xd0 [59.222] btrfs_scrub_cancel+0x91/0x100 [btrfs] [59.222] ? __pfx_autoremove_wake_function+0x10/0x10 [59.222] btrfs_commit_transaction+0x572/0xeb0 [btrfs] [59.223] ? start_transaction+0xcb/0x610 [btrfs] [59.223] prepare_to_relocate+0x111/0x1a0 [btrfs] [59.223] relocate_block_group+0x57/0x5d0 [btrfs] [59.223] ? btrfs_wait_nocow_writers+0x25/0xb0 [btrfs] [59.223] btrfs_relocate_block_group+0x248/0x3c0 [btrfs] [59.224] ? __pfx_autoremove_wake_function+0x10/0x10 [59.224] btrfs_relocate_chunk+0x3b/0x150 [btrfs] [59.224] btrfs_balance+0x8ff/0x11d0 [btrfs] [59.224] ? __kmem_cache_alloc_node+0x14a/0x410 [59.224] btrfs_ioctl+0x2334/0x32c0 [btrfs] [59.225] ? mod_objcg_state+0xd2/0x360 [59.225] ? refill_obj_stock+0xb0/0x160 [59.225] ? seq_release+0x25/0x30 [59.225] ? __rseq_handle_notify_resume+0x3b5/0x4b0 [59.225] ? percpu_counter_add_batch+0x2e/0xa0 [59.225] ? __x64_sys_ioctl+0x88/0xc0 [59.225] __x64_sys_ioctl+0x88/0xc0 [59.225] do_syscall_64+0x38/0x90 [59.225] entry_SYSCALL_64_after_hwframe+0x72/0xdc [59.225] RIP: 0033:0x7f381a6ffe9b [59.225] RSP: 002b:00007ffd45ecf060 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [59.225] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f381a6ffe9b [59.225] RDX: 00007ffd45ecf150 RSI: 00000000c4009420 RDI: 0000000000000003 [59.225] RBP: 0000000000000003 R08: 0000000000000013 R09: 0000000000000000 [59.225] R10: 00007f381a60c878 R11: 0000000000000246 R12: 00007ffd45ed0423 [59.225] R13: 00007ffd45ecf150 R14: 0000000000000000 R15: 00007ffd45ecf148 [59.225] </TASK>
What happens is the following:
1) A scrub is running, so fs_info->scrubs_running is 1;
2) Task A starts block group relocation, and at btrfs_relocate_chunk() it pauses scrub by calling btrfs_scrub_pause(). That increments fs_info->scrub_pause_req from 0 to 1 and waits for the scrub task to pause (for fs_info->scrubs_paused to be == to fs_info->scrubs_running);
3) The scrub task pauses at scrub_pause_off(), waiting for fs_info->scrub_pause_req to decrease to 0;
4) Task A then enters btrfs_relocate_block_group(), and down that call chain we start a transaction and then attempt to commit it;
5) When task A calls btrfs_commit_transaction(), it either will do the commit itself or wait for some other task that already started the commit of the transaction - it doesn't matter which case;
6) The transaction commit enters state TRANS_STATE_COMMIT_START;
7) An error happens during the transaction commit, like -ENOSPC when running delayed refs or delayed items for example;
8) This results in calling transaction.c:cleanup_transaction(), where we call btrfs_scrub_cancel(), incrementing fs_info->scrub_cancel_req from 0 to 1, and blocking this task waiting for fs_info->scrubs_running to decrease to 0;
9) From this point on, both the transaction commit and the scrub task hang forever:
1) The transaction commit is waiting for fs_info->scrubs_running to
be decreased to 0;
2) The scrub task is at scrub_pause_off() waiting for
fs_info->scrub_pause_req to decrease to 0 - so it can not proceed
to stop the scrub and decrement fs_info->scrubs_running from 0 to 1.Therefore resulting in a deadlock.
Fix this by having cleanup_transaction(), called if a transaction commit fails, not call btrfs_scrub_cancel() if relocation is in progress, and having btrfs_relocate_block_group() call btrfs_scrub_cancel() instead if the relocation failed and a transaction abort happened.
This was triggered with btrfs/061 from fstests.
--- fs/btrfs/transaction.c | 15 ++++++++++++++- fs/btrfs/volumes.c | 9 ++++++++- 2 files changed, 22 insertions(+), 2 deletions(-)
fs/btrfs/transaction.c +14 -1
@@ -2009,7 +2009,20 @@ static void cleanup_transaction(struct bif (current->journal_info == trans) current->journal_info =NULL ; -btrfs_scrub_cancel (fs_info); + +/* +* If relocation is running, we can't cancel scrub because that will +* result in a deadlock. Before relocating a block group, relocation +* pauses scrub, then starts and commits a transaction before unpausing +* scrub. If the transaction commit is being done by the relocation +* task or triggered by another task and the relocation task is waiting +* for the commit, and we end up here due to an error in the commit +* path, then calling btrfs_scrub_cancel() will deadlock, as we are +* asking for scrub to stop while having it asked to be paused higher +* above in relocation code. +*/ +if (!test_bit (BTRFS_FS_RELOC_RUNNING , &fs_info->flags)) +btrfs_scrub_cancel (fs_info);kmem_cache_free (btrfs_trans_handle_cachep, trans); }
fs/btrfs/volumes.c +8 -1
@@ -3286,8 +3286,15 @@ int btrfs_relocate_chunk(struct btrfs_fsbtrfs_scrub_pause (fs_info); ret =btrfs_relocate_block_group (fs_info, chunk_offset);btrfs_scrub_continue (fs_info); -if (ret) +if (ret) { +/* +* If we had a transaction abort, stop all running scrubs. +* See transaction.c:cleanup_transaction() why we do it here. +*/ +if (BTRFS_FS_ERROR (fs_info)) +btrfs_scrub_cancel (fs_info);return ret; + } block_group =btrfs_lookup_block_group (fs_info, chunk_offset);if (!block_group)
Greg Kroah-Hartman
maintainerPATCH 131/181 btrfs: fix race between quota disable and quota assign ioctls
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
commit 2f1a6be12ab6c8470d5776e68644726c94257c54 upstream.
The quota assign ioctl can currently run in parallel with a quota disable ioctl call. The assign ioctl uses the quota root, while the disable ioctl frees that root, and therefore we can have a use-after-free triggered in the assign ioctl, leading to a trace like the following when KASAN is enabled:
[672.723][T736] BUG: KASAN: slab-use-after-free in btrfs_search_slot+0x2962/0x2db0 [672.723][T736] Read of size 8 at addr ffff888022ec0208 by task btrfs_search_sl/27736 [672.724][T736] [672.725][T736] CPU: 1 PID: 27736 Comm: btrfs_search_sl Not tainted 6.3.0-rc3 #37 [672.723][T736] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 [672.727][T736] Call Trace: [672.728][T736] <TASK> [672.728][T736] dump_stack_lvl+0xd9/0x150 [672.725][T736] print_report+0xc1/0x5e0 [672.720][T736] ? __virt_addr_valid+0x61/0x2e0 [672.727][T736] ? __phys_addr+0xc9/0x150 [672.725][T736] ? btrfs_search_slot+0x2962/0x2db0 [672.722][T736] kasan_report+0xc0/0xf0 [672.729][T736] ? btrfs_search_slot+0x2962/0x2db0 [672.724][T736] btrfs_search_slot+0x2962/0x2db0 [672.723][T736] ? fs_reclaim_acquire+0xba/0x160 [672.722][T736] ? split_leaf+0x13d0/0x13d0 [672.726][T736] ? rcu_is_watching+0x12/0xb0 [672.723][T736] ? kmem_cache_alloc+0x338/0x3c0 [672.722][T736] update_qgroup_status_item+0xf7/0x320 [672.724][T736] ? add_qgroup_rb+0x3d0/0x3d0 [672.739][T736] ? do_raw_spin_lock+0x12d/0x2b0 [672.730][T736] ? spin_bug+0x1d0/0x1d0 [672.737][T736] btrfs_run_qgroups+0x5de/0x840 [672.730][T736] ? btrfs_qgroup_rescan_worker+0xa70/0xa70 [672.738][T736] ? __del_qgroup_relation+0x4ba/0xe00 [672.738][T736] btrfs_ioctl+0x3d58/0x5d80 [672.735][T736] ? tomoyo_path_number_perm+0x16a/0x550 [672.737][T736] ? tomoyo_execute_permission+0x4a0/0x4a0 [672.731][T736] ? btrfs_ioctl_get_supported_features+0x50/0x50 [672.737][T736] ? __sanitizer_cov_trace_switch+0x54/0x90 [672.734][T736] ? do_vfs_ioctl+0x132/0x1660 [672.730][T736] ? vfs_fileattr_set+0xc40/0xc40 [672.730][T736] ? _raw_spin_unlock_irq+0x2e/0x50 [672.732][T736] ? sigprocmask+0xf2/0x340 [672.737][T736] ? __fget_files+0x26a/0x480 [672.732][T736] ? bpf_lsm_file_ioctl+0x9/0x10 [672.738][T736] ? btrfs_ioctl_get_supported_features+0x50/0x50 [672.736][T736] __x64_sys_ioctl+0x198/0x210 [672.736][T736] do_syscall_64+0x39/0xb0 [672.731][T736] entry_SYSCALL_64_after_hwframe+0x63/0xcd [672.739][T736] RIP: 0033:0x4556ad [672.742][T736] </TASK> [672.743][T736] [672.748][T736] Allocated by task 27677: [672.743][T736] kasan_save_stack+0x22/0x40 [672.741][T736] kasan_set_track+0x25/0x30 [672.741][T736] __kasan_kmalloc+0xa4/0xb0 [672.749][T736] btrfs_alloc_root+0x48/0x90 [672.746][T736] btrfs_create_tree+0x146/0xa20 [672.744][T736] btrfs_quota_enable+0x461/0x1d20 [672.743][T736] btrfs_ioctl+0x4a1c/0x5d80 [672.747][T736] __x64_sys_ioctl+0x198/0x210 [672.749][T736] do_syscall_64+0x39/0xb0 [672.744][T736] entry_SYSCALL_64_after_hwframe+0x63/0xcd [672.756][T736] [672.757][T736] Freed by task 27677: [672.759][T736] kasan_save_stack+0x22/0x40 [672.759][T736] kasan_set_track+0x25/0x30 [672.756][T736] kasan_save_free_info+0x2e/0x50 [672.751][T736] ____kasan_slab_free+0x162/0x1c0 [672.758][T736] slab_free_freelist_hook+0x89/0x1c0 [672.752][T736] __kmem_cache_free+0xaf/0x2e0 [672.752][T736] btrfs_put_root+0x1ff/0x2b0 [672.759][T736] btrfs_quota_disable+0x80a/0xbc0 [672.752][T736] btrfs_ioctl+0x3e5f/0x5d80 [672.756][T736] __x64_sys_ioctl+0x198/0x210 [672.753][T736] do_syscall_64+0x39/0xb0 [672.765][T736] entry_SYSCALL_64_after_hwframe+0x63/0xcd [672.769][T736] [672.768][T736] The buggy address belongs to the object at ffff888022ec0000 [672.768][T736] which belongs to the cache kmalloc-4k of size 4096 [672.769][T736] The buggy address is located 520 bytes inside of [672.769][T736] freed 4096-byte region [ffff888022ec0000, ffff888022ec1000) [672.760][T736] [672.764][T736] The buggy address belongs to the physical page: [672.761][T736] page:ffffea00008bb000 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x22ec0 [672.766][T736] head:ffffea00008bb000 order:3 entire_mapcount:0 nr_pages_mapped:0 pincount:0 [672.779][T736] flags: 0xfff00000010200(slab|head|node=0|zone=1|lastcpupid=0x7ff) [672.770][T736] raw: 00fff00000010200 ffff888012842140 ffffea000054ba00 dead000000000002 [672.770][T736] raw: 0000000000000000 0000000000040004 00000001ffffffff 0000000000000000 [672.771][T736] page dumped because: kasan: bad access detected [672.778][T736] page_owner tracks the page as allocated [672.777][T736] page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd2040(__GFP_IO|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 88 [672.779][T736] get_page_from_freelist+0x119c/0x2d50 [672.779][T736] __alloc_pages+0x1cb/0x4a0 [672.776][T736] alloc_pages+0x1aa/0x270 [672.773][T736] allocate_slab+0x260/0x390 [672.771][T736] ___slab_alloc+0xa9a/0x13e0 [672.778][T736] __slab_alloc.constprop.0+0x56/0xb0 [672.771][T736] __kmem_cache_alloc_node+0x136/0x320 [672.789][T736] __kmalloc+0x4e/0x1a0 [672.783][T736] tomoyo_realpath_from_path+0xc3/0x600 [672.781][T736] tomoyo_path_perm+0x22f/0x420 [672.782][T736] tomoyo_path_unlink+0x92/0xd0 [672.780][T736] security_path_unlink+0xdb/0x150 [672.788][T736] do_unlinkat+0x377/0x680 [672.788][T736] __x64_sys_unlink+0xca/0x110 [672.789][T736] do_syscall_64+0x39/0xb0 [672.783][T736] entry_SYSCALL_64_after_hwframe+0x63/0xcd [672.784][T736] page last free stack trace: [672.787][T736] free_pcp_prepare+0x4e5/0x920 [672.787][T736] free_unref_page+0x1d/0x4e0 [672.784][T736] __unfreeze_partials+0x17c/0x1a0 [672.797][T736] qlist_free_all+0x6a/0x180 [672.796][T736] kasan_quarantine_reduce+0x189/0x1d0 [672.797][T736] __kasan_slab_alloc+0x64/0x90 [672.793][T736] kmem_cache_alloc+0x17c/0x3c0 [672.799][T736] getname_flags.part.0+0x50/0x4e0 [672.799][T736] getname_flags+0x9e/0xe0 [672.792][T736] vfs_fstatat+0x77/0xb0 [672.791][T736] __do_sys_newlstat+0x84/0x100 [672.798][T736] do_syscall_64+0x39/0xb0 [672.796][T736] entry_SYSCALL_64_after_hwframe+0x63/0xcd [672.790][T736] [672.791][T736] Memory state around the buggy address: [672.799][T736] ffff888022ec0100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [672.805][T736] ffff888022ec0180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [672.802][T736] >ffff888022ec0200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [672.809][T736] ^ [672.809][T736] ffff888022ec0280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [672.809][T736] ffff888022ec0300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
Fix this by having the qgroup assign ioctl take the qgroup ioctl mutex before calling btrfs_run_qgroups(), which is what all qgroup ioctls should call.
--- fs/btrfs/ioctl.c | 2 ++ fs/btrfs/qgroup.c | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-)
fs/btrfs/ioctl.c +2 -0
@@ -4621,7 +4621,9 @@ static long btrfs_ioctl_qgroup_assign(st }/* update qgroup status and info */ +mutex_lock (&fs_info->qgroup_ioctl_lock); err =btrfs_run_qgroups (trans); +mutex_unlock (&fs_info->qgroup_ioctl_lock);if (err <0 )btrfs_handle_fs_error (fs_info, err,"failed to update qgroup status and info" );
fs/btrfs/qgroup.c +10 -1
@@ -2812,13 +2812,22 @@ cleanup: }/* -* called from commit_transaction. Writes all changed qgroups to disk. +* Writes all changed qgroups to disk. +* Called by the transaction commit path and the qgroup assign ioctl. */ int btrfs_run_qgroups (struct btrfs_trans_handle *trans) {struct btrfs_fs_info *fs_info = trans->fs_info;int ret =0 ; +/* +* In case we are called from the qgroup assign ioctl, assert that we +* are holding the qgroup_ioctl_lock, otherwise we can race with a quota +* disable operation (ioctl) and access a freed quota root. +*/ +if (trans->transaction->state !=TRANS_STATE_COMMIT_DOING ) +lockdep_assert_held (&fs_info->qgroup_ioctl_lock); +if (!fs_info->quota_root)return ret;
Greg Kroah-Hartman
maintainerPATCH 132/181 btrfs: scan device in non-exclusive mode
In reply to Greg Kroah-HartmanFrom: Anand Jain <[email protected]>
commit 50d281fc434cb8e2497f5e70a309ccca6b1a09f0 upstream.
This fixes mkfs/mount/check failures due to race with systemd-udevd scan.
During the device scan initiated by systemd-udevd, other user space EXCL operations such as mkfs, mount, or check may get blocked and result in a "Device or resource busy" error. This is because the device scan process opens the device with the EXCL flag in the kernel.
Two reports were received:
- btrfs/179 test case, where the fsck command failed with the -EBUSY error
- LTP pwritev03 test case, where mkfs.vfs failed with
the -EBUSY error, when mkfs.vfs tried to overwrite old btrfs filesystem on the device.
In both cases, fsck and mkfs (respectively) were racing with a systemd-udevd device scan, and systemd-udevd won, resulting in the -EBUSY error for fsck and mkfs.
Reproducing the problem has been difficult because there is a very small window during which these userspace threads can race to acquire the exclusive device open. Even on the system where the problem was observed, the problem occurrences were anywhere between 10 to 400 iterations and chances of reproducing decreases with debug printk()s.
However, an exclusive device open is unnecessary for the scan process, as there are no write operations on the device during scan. Furthermore, during the mount process, the superblock is re-read in the below function call chain:
btrfs_mount_root
btrfs_open_devices
open_fs_devices
btrfs_open_one_device
btrfs_get_bdev_and_sb
So, to fix this issue, removes the FMODE_EXCL flag from the scan operation, and add a comment.
The case where mkfs may still write to the device and a scan is running, the btrfs signature is not written at that time so scan will not recognize such device.
--- fs/btrfs/volumes.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
fs/btrfs/volumes.c +10 -1
@@ -1379,8 +1379,17 @@ struct btrfs_device *btrfs_scan_one_devi* So, we need to add a special mount option to scan for * later supers, using BTRFS_SUPER_MIRROR_MAX instead */ - flags |=FMODE_EXCL ; +/* +* Avoid using flag |= FMODE_EXCL here, as the systemd-udev may +* initiate the device scan which may race with the user's mount +* or mkfs command, resulting in failure. +* Since the device scan is solely for reading purposes, there is +* no need for FMODE_EXCL. Additionally, the devices are read again +* during the mount process. It is ok to get some inconsistent +* values temporarily, as the device paths of the fsid are the only +* required information for assembling the volume. +*/ bdev =blkdev_get_by_path (path, flags, holder);if (IS_ERR (bdev))return ERR_CAST (bdev);
Greg Kroah-Hartman
maintainerPATCH 133/181 zonefs: Do not propagate iomap_dio_rw() ENOTBLK error to user space
In reply to Greg Kroah-HartmanFrom: Damien Le Moal <[email protected]>
commit 77af13ba3c7f91d91c377c7e2d122849bbc17128 upstream.
The call to invalidate_inode_pages2_range() in __iomap_dio_rw() may fail, in which case -ENOTBLK is returned and this error code is propagated back to user space trhough iomap_dio_rw() -> zonefs_file_dio_write() return chain. This error code is fairly obscure and may confuse the user. Avoid this and be consistent with the behavior of zonefs_file_dio_append() for similar invalidate_inode_pages2_range() errors by returning -EBUSY to user space when iomap_dio_rw() returns -ENOTBLK.
--- fs/zonefs/file.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
fs/zonefs/file.c +12 -2
@@ -567,11 +567,21 @@ static ssize_t zonefs_file_dio_write(str append = sync; } -if (append) +if (append) { ret =zonefs_file_dio_append (iocb, from); -else + }else { +/* +* iomap_dio_rw() may return ENOTBLK if there was an issue with +* page invalidation. Overwrite that error code with EBUSY to +* be consistent with zonefs_file_dio_append() return value for +* similar issues. +*/ ret =iomap_dio_rw (iocb, from, &zonefs_write_iomap_ops, &zonefs_write_dio_ops,0 ,NULL ,0 ); +if (ret == -ENOTBLK ) + ret = -EBUSY ; + } +if (zonefs_zone_is_seq (z) && (ret >0 || ret == -EIOCBQUEUED )) {if (ret >0 )
Greg Kroah-Hartman
maintainerPATCH 134/181 block/io_uring: pass in issue_flags for uring_cmd task_work handling
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit 9d2789ac9d60c049d26ef6d3005d9c94c5a559e9 upstream.
io_uring_cmd_done() currently assumes that the uring_lock is held when invoked, and while it generally is, this is not guaranteed. Pass in the issue_flags associated with it, so that we have IO_URING_F_UNLOCKED available to be able to lock the CQ ring appropriately when completing events.
--- drivers/block/ublk_drv.c | 31 ++++++++++++++++++------------- drivers/nvme/host/ioctl.c | 14 ++++++++------ include/linux/io_uring.h | 11 ++++++----- io_uring/uring_cmd.c | 10 ++++++---- 4 files changed, 38 insertions(+), 28 deletions(-)
drivers/block/ublk_drv.c +18 -13
@@ -656,7 +656,8 @@ static void __ublk_fail_req(struct ublk_ } } -static void ubq_complete_io_cmd (struct ublk_io *io,int res) +static void ubq_complete_io_cmd (struct ublk_io *io,int res, +unsigned issue_flags) {/* mark this cmd owned by ublksrv */ io->flags |=UBLK_IO_FLAG_OWNED_BY_SRV ;
@@ -668,7 +669,7 @@ static void ubq_complete_io_cmd(struct u io->flags &= ~UBLK_IO_FLAG_ACTIVE ;/* tell ublksrv one io request is coming */ -io_uring_cmd_done (io->cmd, res,0 ); +io_uring_cmd_done (io->cmd, res,0 , issue_flags); }#define UBLK_REQUEUE_DELAY_MS 3
@@ -685,7 +686,8 @@ static inline void __ublk_abort_rq(strucmod_delayed_work (system_wq, &ubq->dev->monitor_work,0 ); } -static inline void __ublk_rq_task_work (struct request *req) +static inline void __ublk_rq_task_work (struct request *req, +unsigned issue_flags) {struct ublk_queue *ubq = req->mq_hctx->driver_data;int tag = req->tag;
@@ -723,7 +725,7 @@ static inline void __ublk_rq_task_work(spr_devel ("%s: need get data. op %d, qid %d tag %d io_flags %x\n" , __func__, io->cmd->cmd_op, ubq->q_id, req->tag, io->flags); -ubq_complete_io_cmd (io,UBLK_IO_RES_NEED_GET_DATA ); +ubq_complete_io_cmd (io,UBLK_IO_RES_NEED_GET_DATA , issue_flags);return ; }/*
@@ -761,17 +763,18 @@ static inline void __ublk_rq_task_work(s mapped_bytes >>9 ; } -ubq_complete_io_cmd (io,UBLK_IO_RES_OK ); +ubq_complete_io_cmd (io,UBLK_IO_RES_OK , issue_flags); } -static inline void ublk_forward_io_cmds (struct ublk_queue *ubq) +static inline void ublk_forward_io_cmds (struct ublk_queue *ubq, +unsigned issue_flags) {struct llist_node *io_cmds =llist_del_all (&ubq->io_cmds);struct ublk_rq_data *data, *tmp; io_cmds =llist_reverse_order (io_cmds);llist_for_each_entry_safe (data, tmp, io_cmds, node) -__ublk_rq_task_work (blk_mq_rq_from_pdu (data)); +__ublk_rq_task_work (blk_mq_rq_from_pdu (data), issue_flags); }static inline void ublk_abort_io_cmds (struct ublk_queue *ubq)
@@ -783,12 +786,12 @@ static inline void ublk_abort_io_cmds(st__ublk_abort_rq (ubq,blk_mq_rq_from_pdu (data)); } -static void ublk_rq_task_work_cb (struct io_uring_cmd *cmd) +static void ublk_rq_task_work_cb (struct io_uring_cmd *cmd,unsigned issue_flags) {struct ublk_uring_cmd_pdu *pdu =ublk_get_uring_cmd_pdu (cmd);struct ublk_queue *ubq = pdu->ubq; -ublk_forward_io_cmds (ubq); +ublk_forward_io_cmds (ubq, issue_flags); }static void ublk_rq_task_work_fn (struct callback_head *work)
@@ -797,8 +800,9 @@ static void ublk_rq_task_work_fn(struct struct ublk_rq_data, work);struct request *req =blk_mq_rq_from_pdu (data);struct ublk_queue *ubq = req->mq_hctx->driver_data; +unsigned issue_flags =IO_URING_F_UNLOCKED ; -ublk_forward_io_cmds (ubq); +ublk_forward_io_cmds (ubq, issue_flags); }static void ublk_queue_cmd (struct ublk_queue *ubq,struct request *rq)
@@ -1052,7 +1056,8 @@ static void ublk_cancel_queue(struct ublstruct ublk_io *io = &ubq->ios[i];if (io->flags &UBLK_IO_FLAG_ACTIVE ) -io_uring_cmd_done (io->cmd,UBLK_IO_RES_ABORT ,0 ); +io_uring_cmd_done (io->cmd,UBLK_IO_RES_ABORT ,0 , +IO_URING_F_UNLOCKED ); }/* all io commands are canceled */
@@ -1295,7 +1300,7 @@ static int ublk_ch_uring_cmd(struct io_ureturn -EIOCBQUEUED ; out: -io_uring_cmd_done (cmd, ret,0 ); +io_uring_cmd_done (cmd, ret,0 , issue_flags);pr_devel ("%s: complete: cmd op %d, tag %d ret %x io_flags %x\n" , __func__, cmd_op, tag, ret, io->flags);return -EIOCBQUEUED ;
@@ -2053,7 +2058,7 @@ static int ublk_ctrl_uring_cmd(struct iobreak ; } out: -io_uring_cmd_done (cmd, ret,0 ); +io_uring_cmd_done (cmd, ret,0 , issue_flags);pr_devel ("%s: cmd done ret %d cmd_op %x, dev id %d qid %d\n" , __func__, ret, cmd->cmd_op, header->dev_id, header->queue_id);return -EIOCBQUEUED ;
drivers/nvme/host/ioctl.c +8 -6
@@ -387,7 +387,8 @@ static inline struct nvme_uring_cmd_pdureturn (struct nvme_uring_cmd_pdu *)&ioucmd->pdu; } -static void nvme_uring_task_meta_cb (struct io_uring_cmd *ioucmd) +static void nvme_uring_task_meta_cb (struct io_uring_cmd *ioucmd, +unsigned issue_flags) {struct nvme_uring_cmd_pdu *pdu =nvme_uring_cmd_pdu (ioucmd);struct request *req = pdu->req;
@@ -408,17 +409,18 @@ static void nvme_uring_task_meta_cb(strublk_rq_unmap_user (req->bio);blk_mq_free_request (req); -io_uring_cmd_done (ioucmd, status, result); +io_uring_cmd_done (ioucmd, status, result, issue_flags); } -static void nvme_uring_task_cb (struct io_uring_cmd *ioucmd) +static void nvme_uring_task_cb (struct io_uring_cmd *ioucmd, +unsigned issue_flags) {struct nvme_uring_cmd_pdu *pdu =nvme_uring_cmd_pdu (ioucmd);if (pdu->bio)blk_rq_unmap_user (pdu->bio); -io_uring_cmd_done (ioucmd, pdu->nvme_status, pdu->u.result); +io_uring_cmd_done (ioucmd, pdu->nvme_status, pdu->u.result, issue_flags); } static enum rq_end_io_ret nvme_uring_cmd_end_io(struct request *req,
@@ -440,7 +442,7 @@ static enum rq_end_io_ret nvme_uring_cmd* Otherwise, move the completion to task work. */ if (cookie !=NULL &&blk_rq_is_poll (req)) -nvme_uring_task_cb (ioucmd); +nvme_uring_task_cb (ioucmd,IO_URING_F_UNLOCKED );else io_uring_cmd_complete_in_task (ioucmd, nvme_uring_task_cb);
@@ -462,7 +464,7 @@ static enum rq_end_io_ret nvme_uring_cmd* Otherwise, move the completion to task work. */ if (cookie !=NULL &&blk_rq_is_poll (req)) -nvme_uring_task_meta_cb (ioucmd); +nvme_uring_task_meta_cb (ioucmd,IO_URING_F_UNLOCKED );else io_uring_cmd_complete_in_task (ioucmd, nvme_uring_task_meta_cb);
include/linux/io_uring.h +6 -5
@@ -26,7 +26,7 @@ struct io_uring_cmd {const void *cmd;union {/* callback to defer completions to task context */ -void (*task_work_cb)(struct io_uring_cmd *cmd); +void (*task_work_cb)(struct io_uring_cmd *cmd,unsigned );/* used for polled completion */ void *cookie; };
@@ -38,9 +38,10 @@ struct io_uring_cmd {#if defined(CONFIG_IO_URING )int io_uring_cmd_import_fixed (u64 ubuf,unsigned long len,int rw,struct iov_iter *iter,void *ioucmd); -void io_uring_cmd_done (struct io_uring_cmd *cmd,ssize_t ret,ssize_t res2); +void io_uring_cmd_done (struct io_uring_cmd *cmd,ssize_t ret,ssize_t res2, +unsigned issue_flags);void io_uring_cmd_complete_in_task (struct io_uring_cmd *ioucmd, -void (*task_work_cb)(struct io_uring_cmd *)); +void (*task_work_cb)(struct io_uring_cmd *,unsigned ));struct sock *io_uring_get_socket (struct file *file);void __io_uring_cancel (bool cancel_all);void __io_uring_free (struct task_struct *tsk);
@@ -71,11 +72,11 @@ static inline int io_uring_cmd_import_fireturn -EOPNOTSUPP ; }static inline void io_uring_cmd_done (struct io_uring_cmd *cmd,ssize_t ret, -ssize_t ret2) +ssize_t ret2,unsigned issue_flags) { }static inline void io_uring_cmd_complete_in_task (struct io_uring_cmd *ioucmd, -void (*task_work_cb)(struct io_uring_cmd *)) +void (*task_work_cb)(struct io_uring_cmd *,unsigned )) { }static inline struct sock *io_uring_get_socket (struct file *file)
io_uring/uring_cmd.c +6 -4
@@ -15,12 +15,13 @@static void io_uring_cmd_work (struct io_kiocb *req,bool *locked) { struct io_uring_cmd *ioucmd = io_kiocb_to_cmd(req, struct io_uring_cmd); +unsigned issue_flags = *locked ?0 :IO_URING_F_UNLOCKED ; - ioucmd->task_work_cb (ioucmd); + ioucmd->task_work_cb (ioucmd, issue_flags); }void io_uring_cmd_complete_in_task (struct io_uring_cmd *ioucmd, -void (*task_work_cb)(struct io_uring_cmd *)) +void (*task_work_cb)(struct io_uring_cmd *,unsigned )) {struct io_kiocb *req =cmd_to_io_kiocb (ioucmd);
@@ -42,7 +43,8 @@ static inline void io_req_set_cqe32_extr* Called by consumers of io_uring_cmd, if they originally returned * -EIOCBQUEUED upon receiving the command. */ -void io_uring_cmd_done (struct io_uring_cmd *ioucmd,ssize_t ret,ssize_t res2) +void io_uring_cmd_done (struct io_uring_cmd *ioucmd,ssize_t ret,ssize_t res2, +unsigned issue_flags) {struct io_kiocb *req =cmd_to_io_kiocb (ioucmd);
@@ -56,7 +58,7 @@ void io_uring_cmd_done(struct io_uring_c/* order with io_iopoll_req_issued() checking ->iopoll_complete */ smp_store_release (&req->iopoll_completed,1 ); else - __io_req_complete(req, 0); +__io_req_complete (req ,issue_flags ); }EXPORT_SYMBOL_GPL (io_uring_cmd_done);
Greg Kroah-Hartman
maintainerPATCH 135/181 io_uring/poll: clear single/double poll flags on poll arming
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit 005308f7bdacf5685ed1a431244a183dbbb9e0e8 upstream.
Unless we have at least one entry queued, then don't call into io_poll_remove_entries(). Normally this isn't possible, but if we retry poll then we can have ->nr_entries cleared again as we're setting it up. If this happens for a poll retry, then we'll still have at least REQ_F_SINGLE_POLL set. io_poll_remove_entries() then thinks it has entries to remove.
Clear REQ_F_SINGLE_POLL and REQ_F_DOUBLE_POLL unconditionally when arming a poll request.
--- io_uring/poll.c | 1 + 1 file changed, 1 insertion(+)
io_uring/poll.c +1 -0
@@ -742,6 +742,7 @@ int io_arm_poll_handler(struct io_kiocb apoll =io_req_alloc_apoll (req, issue_flags);if (!apoll)return IO_APOLL_ABORTED ; + req->flags &= ~(REQ_F_SINGLE_POLL |REQ_F_DOUBLE_POLL ); req->flags |=REQ_F_POLLED ; ipt.pt._qproc = io_async_queue_proc;
Greg Kroah-Hartman
maintainerPATCH 136/181 io_uring/rsrc: fix rogue rsrc node grabbing
In reply to Greg Kroah-HartmanFrom: Pavel Begunkov <[email protected]>
commit 4ff0b50de8cabba055efe50bbcb7506c41a69835 upstream.
We should not be looking at ctx->rsrc_node and anyhow modifying the node without holding uring_lock, grabbing references in such a way is not safe either.
--- io_uring/rsrc.h | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
io_uring/rsrc.h +5 -7
@@ -143,15 +143,13 @@ static inline void io_req_set_rsrc_node( unsigned int issue_flags) {if (!req->rsrc_node) { - req->rsrc_node = ctx->rsrc_node; +io_ring_submit_lock (ctx, issue_flags); -if (!(issue_flags &IO_URING_F_UNLOCKED )) { -lockdep_assert_held (&ctx->uring_lock); +lockdep_assert_held (&ctx->uring_lock); -io_charge_rsrc_node (ctx); - }else { -percpu_ref_get (&req->rsrc_node->refs); - } + req->rsrc_node = ctx->rsrc_node; +io_charge_rsrc_node (ctx); +io_ring_submit_unlock (ctx, issue_flags); } }
Greg Kroah-Hartman
maintainerPATCH 137/181 io_uring: fix poll/netmsg alloc caches
In reply to Greg Kroah-HartmanFrom: Pavel Begunkov <[email protected]>
commit fd30d1cdcc4ff405fc54765edf2e11b03f2ed4f3 upstream.
We increase cache->nr_cached when we free into the cache but don't decrease when we take from it, so in some time we'll get an empty cache with cache->nr_cached larger than IO_ALLOC_CACHE_MAX, that fails io_alloc_cache_put() and effectively disables caching.
--- io_uring/alloc_cache.h | 1 + 1 file changed, 1 insertion(+)
io_uring/alloc_cache.h +1 -0
@@ -27,6 +27,7 @@ static inline struct io_cache_entry *io_alloc_cache_get(struct io_alloc_cache *cstruct hlist_node *node = cache->list.first;hlist_del (node); + cache->nr_cached--; return container_of(node, struct io_cache_entry, node); }
Signature · 1 line
2.40.0
Greg Kroah-Hartman
maintainerPATCH 138/181 vmxnet3: use gro callback when UPT is enabled
In reply to Greg Kroah-HartmanFrom: Ronak Doshi <[email protected]>
commit 3bced313b9a5a237c347e0f079c8c2fe4b3935aa upstream.
Currently, vmxnet3 uses GRO callback only if LRO is disabled. However, on smartNic based setups where UPT is supported, LRO can be enabled from guest VM but UPT devicve does not support LRO as of now. In such cases, there can be performance degradation as GRO is not being done.
This patch fixes this issue by calling GRO API when UPT is enabled. We use updateRxProd to determine if UPT mode is active or not.
To clarify few things discussed over the thread:
The patch is not neglecting any feature bits nor disabling GRO. It uses GRO callback when UPT is active as LRO is not available in UPT. GRO callback cannot be used as default for all cases as it degrades performance for non-UPT cases or for cases when LRO is already done in ESXi.
--- drivers/net/vmxnet3/vmxnet3_drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/vmxnet3/vmxnet3_drv.c +3 -1
@@ -1688,7 +1688,9 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,if (unlikely (rcd->ts))__vlan_hwaccel_put_tag (skb,htons (ETH_P_8021Q ), rcd->tci); -if (adapter->netdev->features &NETIF_F_LRO ) +/* Use GRO callback if UPT is enabled */ +if ((adapter->netdev->features &NETIF_F_LRO ) && + !rq->shared->updateRxProd)netif_receive_skb (skb);else napi_gro_receive (&rq->napi, skb);
Signature · 1 line
2.40.0
Greg Kroah-Hartman
maintainerPATCH 139/181 zonefs: Always invalidate last cached page on append write
In reply to Greg Kroah-HartmanFrom: Damien Le Moal <[email protected]>
commit c1976bd8f23016d8706973908f2bb0ac0d852a8f upstream.
When a direct append write is executed, the append offset may correspond to the last page of a sequential file inode which might have been cached already by buffered reads, page faults with mmap-read or non-direct readahead. To ensure that the on-disk and cached data is consistant for such last cached page, make sure to always invalidate it in zonefs_file_dio_append(). If the invalidation fails, return -EBUSY to userspace to differentiate from IO errors.
This invalidation will always be a no-op when the FS block size (device zone write granularity) is equal to the page size (e.g. 4K).
--- fs/zonefs/file.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
fs/zonefs/file.c +14 -0
@@ -382,6 +382,7 @@ static ssize_t zonefs_file_dio_append(ststruct zonefs_zone *z =zonefs_inode_zone (inode);struct block_device *bdev = inode->i_sb->s_bdev;unsigned int max =bdev_max_zone_append_sectors (bdev); +pgoff_t start, end;struct bio *bio;ssize_t size;int nr_pages;
@@ -390,6 +391,19 @@ static ssize_t zonefs_file_dio_append(st max =ALIGN_DOWN (max <<SECTOR_SHIFT , inode->i_sb->s_blocksize);iov_iter_truncate (from, max); +/* +* If the inode block size (zone write granularity) is smaller than the +* page size, we may be appending data belonging to the last page of the +* inode straddling inode->i_size, with that page already cached due to +* a buffered read or readahead. So make sure to invalidate that page. +* This will always be a no-op for the case where the block size is +* equal to the page size. +*/ + start = iocb->ki_pos >>PAGE_SHIFT ; + end = (iocb->ki_pos +iov_iter_count (from) -1 ) >>PAGE_SHIFT ; +if (invalidate_inode_pages2_range (inode->i_mapping, start, end)) +return -EBUSY ; + nr_pages =iov_iter_npages (from,BIO_MAX_VECS );if (!nr_pages)return 0 ;
Greg Kroah-Hartman
maintainerPATCH 140/181 dm: fix __send_duplicate_bios() to always allow for splitting IO
In reply to Greg Kroah-HartmanFrom: Mike Snitzer <[email protected]>
commit 666eed46769d929c3e13636134ecfc67d75ef548 upstream.
Commit 7dd76d1feec70 ("dm: improve bio splitting and associated IO accounting") only called setup_split_accounting() from __send_duplicate_bios() if a single bio were being issued. But the case where duplicate bios are issued must call it too.
Otherwise the bio won't be split and resubmitted (via recursion through block core back to DM) to submit the later portions of a bio (which may map to an entirely different target).
For example, when discarding an entire DM striped device with the following DM table:
vg-lvol0: 0 159744 striped 2 128 7:0 2048 7:1 2048
vg-lvol0: 159744 45056 striped 2 128 7:2 2048 7:3 2048
Before (broken, discards the first striped target's devices twice):
device-mapper: striped: target_stripe=0, bdev=7:0, start=2048 len=79872
device-mapper: striped: target_stripe=1, bdev=7:1, start=2048 len=79872
device-mapper: striped: target_stripe=0, bdev=7:0, start=2049 len=22528
device-mapper: striped: target_stripe=1, bdev=7:1, start=2048 len=22528
After (works as expected):
device-mapper: striped: target_stripe=0, bdev=7:0, start=2048 len=79872
device-mapper: striped: target_stripe=1, bdev=7:1, start=2048 len=79872
device-mapper: striped: target_stripe=0, bdev=7:2, start=2048 len=22528
device-mapper: striped: target_stripe=1, bdev=7:3, start=2048 len=22528
--- drivers/md/dm.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/md/dm.c +2 -0
@@ -1522,6 +1522,8 @@ static int __send_duplicate_bios(struct ret =1 ;break ;default : +if (len) +setup_split_accounting (ci, *len);/* dm_accept_partial_bio() is not supported with shared tio->len_ptr */ alloc_multiple_bios (&blist, ci, ti, num_bios);while ((clone =bio_list_pop (&blist))) {
Greg Kroah-Hartman
maintainerPATCH 141/181 can: j1939: prevent deadlock by moving j1939_sk_errqueue()
In reply to Greg Kroah-HartmanFrom: Oleksij Rempel <[email protected]>
commit d1366b283d94ac4537a4b3a1e8668da4df7ce7e9 upstream.
This commit addresses a deadlock situation that can occur in certain scenarios, such as when running data TP/ETP transfer and subscribing to the error queue while receiving a net down event. The deadlock involves locks in the following order:
3
j1939_session_list_lock -> active_session_list_lock j1939_session_activate
...
j1939_sk_queue_activate_next -> sk_session_queue_lock
...
j1939_xtp_rx_eoma_one
2
j1939_sk_queue_drop_all -> sk_session_queue_lock
...
j1939_sk_netdev_event_netdown -> j1939_socks_lock j1939_netdev_notify
1
j1939_sk_errqueue -> j1939_socks_lock __j1939_session_cancel -> active_session_list_lock j1939_tp_rxtimer
CPU0 CPU1
---- ----
lock(&priv->active_session_list_lock);
lock(&jsk->sk_session_queue_lock);
lock(&priv->active_session_list_lock); lock(&priv->j1939_socks_lock);
The solution implemented in this commit is to move the j1939_sk_errqueue() call out of the active_session_list_lock context, thus preventing the deadlock situation.
--- net/can/j1939/transport.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
net/can/j1939/transport.c +6 -2
@@ -1124,8 +1124,6 @@ static void __j1939_session_cancel(strucif (session->sk)j1939_sk_send_loop_abort (session->sk, session->err); -else -j1939_sk_errqueue (session,J1939_ERRQUEUE_RX_ABORT ); } static void j1939_session_cancel(struct j1939_session *session,
@@ -1140,6 +1138,9 @@ static void j1939_session_cancel(struct }j1939_session_list_unlock (session->priv); + +if (!session->sk) +j1939_sk_errqueue (session,J1939_ERRQUEUE_RX_ABORT ); }static enum hrtimer_restart j1939_tp_txtimer (struct hrtimer *hrtimer)
@@ -1253,6 +1254,9 @@ static enum hrtimer_restart j1939_tp_rxt__j1939_session_cancel (session,J1939_XTP_ABORT_TIMEOUT ); }j1939_session_list_unlock (session->priv); + +if (!session->sk) +j1939_sk_errqueue (session,J1939_ERRQUEUE_RX_ABORT ); }j1939_session_put (session);
Greg Kroah-Hartman
maintainerPATCH 142/181 xen/netback: dont do grant copy across page boundary
In reply to Greg Kroah-HartmanFrom: Juergen Gross <[email protected]>
commit 05310f31ca74673a96567fb14637b7d5d6c82ea5 upstream.
Fix xenvif_get_requests() not to do grant copy operations across local page boundaries. This requires to double the maximum number of copy operations per queue, as each copy could now be split into 2.
Make sure that struct xenvif_tx_cb doesn't grow too large.
--- drivers/net/xen-netback/common.h | 2 +- drivers/net/xen-netback/netback.c | 25 +++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-)
drivers/net/xen-netback/common.h +1 -1
@@ -166,7 +166,7 @@ struct xenvif_queue { /* Per-queue datastruct pending_tx_info pending_tx_info[MAX_PENDING_REQS ];grant_handle_t grant_tx_handle[MAX_PENDING_REQS ]; -struct gnttab_copy tx_copy_ops[MAX_PENDING_REQS ]; +struct gnttab_copy tx_copy_ops[2 *MAX_PENDING_REQS ];struct gnttab_map_grant_ref tx_map_ops[MAX_PENDING_REQS ];struct gnttab_unmap_grant_ref tx_unmap_ops[MAX_PENDING_REQS ];/* passed to gnttab_[un]map_refs with pages under (un)mapping */
drivers/net/xen-netback/netback.c +23 -2
@@ -334,6 +334,7 @@ static int xenvif_count_requests(structstruct xenvif_tx_cb {u16 copy_pending_idx[XEN_NETBK_LEGACY_SLOTS_MAX +1 ];u8 copy_count; +u32 split_mask; };#define XENVIF_TX_CB (skb) ((struct xenvif_tx_cb *)(skb)->cb)
@@ -361,6 +362,8 @@ static inline struct sk_buff *xenvif_allstruct sk_buff *skb =alloc_skb (size +NET_SKB_PAD +NET_IP_ALIGN ,GFP_ATOMIC | __GFP_NOWARN); + +BUILD_BUG_ON (sizeof (*XENVIF_TX_CB (skb)) >sizeof (skb->cb));if (unlikely (skb ==NULL ))return NULL ;
@@ -396,11 +399,13 @@ static void xenvif_get_requests(struct x nr_slots = shinfo->nr_frags +1 ;copy_count (skb) =0 ; +XENVIF_TX_CB (skb)->split_mask =0 ;/* Create copy ops for exactly data_len bytes into the skb head. */ __skb_put (skb, data_len);while (data_len >0 ) {int amount = data_len > txp->size ? txp->size : data_len; +bool split = false; cop->source.u.ref = txp->gref; cop->source.domid = queue->vif->domid;
@@ -413,6 +418,13 @@ static void xenvif_get_requests(struct x cop->dest.u.gmfn =virt_to_gfn (skb->data +skb_headlen (skb) - data_len); +/* Don't cross local page boundary! */ +if (cop->dest.offset + amount >XEN_PAGE_SIZE ) { + amount =XEN_PAGE_SIZE - cop->dest.offset; +XENVIF_TX_CB (skb)->split_mask |=1U <<copy_count (skb); + split = true; + } + cop->len = amount; cop->flags = GNTCOPY_source_gref;
@@ -420,7 +432,8 @@ static void xenvif_get_requests(struct x pending_idx = queue->pending_ring[index];callback_param (queue, pending_idx).ctx =NULL ;copy_pending_idx (skb,copy_count (skb)) = pending_idx; -copy_count (skb)++; +if (!split) +copy_count (skb)++; cop++; data_len -= amount;
@@ -441,7 +454,8 @@ static void xenvif_get_requests(struct x nr_slots--; }else {/* The copy op partially covered the tx_request. -* The remainder will be mapped. +* The remainder will be mapped or copied in the next +* iteration. */ txp->offset += amount; txp->size -= amount;
@@ -539,6 +553,13 @@ static int xenvif_tx_check_gop(struct xe pending_idx =copy_pending_idx (skb, i); newerr = (*gopp_copy)->status; + +/* Split copies need to be handled together. */ +if (XENVIF_TX_CB (skb)->split_mask & (1U << i)) { + (*gopp_copy)++; +if (!newerr) + newerr = (*gopp_copy)->status; + }if (likely (!newerr)) {/* The first frag might still have this slot mapped */ if (i <copy_count (skb) -1 || !sharedslot)
Greg Kroah-Hartman
maintainerPATCH 143/181 net: phy: dp83869: fix default value for tx-/rx-internal-delay
In reply to Greg Kroah-HartmanFrom: Josua Mayer <[email protected]>
commit 82e2c39f9ef78896e9b634dfd82dc042e6956bb7 upstream.
dp83869 internally uses a look-up table for mapping supported delays in nanoseconds to register values.
When specific delays are defined in device-tree, phy_get_internal_delay does the lookup automatically returning an index.
The default case wrongly assigns the nanoseconds value from the lookup table, resulting in numeric value 2000 applied to delay configuration register, rather than the expected index values 0-7 (7 for 2000). Ultimately this issue broke RX for 1Gbps links.
Fix default delay configuration by assigning the intended index value directly.
--- drivers/net/phy/dp83869.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/net/phy/dp83869.c +2 -4
@@ -588,15 +588,13 @@ static int dp83869_of_init(struct phy_de &dp83869_internal_delay[0 ], delay_size, true);if (dp83869->rx_int_delay <0 ) - dp83869->rx_int_delay = - dp83869_internal_delay[DP83869_CLK_DELAY_DEF ]; + dp83869->rx_int_delay =DP83869_CLK_DELAY_DEF ; dp83869->tx_int_delay =phy_get_internal_delay (phydev, dev, &dp83869_internal_delay[0 ], delay_size, false);if (dp83869->tx_int_delay <0 ) - dp83869->tx_int_delay = - dp83869_internal_delay[DP83869_CLK_DELAY_DEF ]; + dp83869->tx_int_delay =DP83869_CLK_DELAY_DEF ;return ret; }
Greg Kroah-Hartman
maintainerPATCH 144/181 modpost: Fix processing of CRCs on 32-bit build machines
In reply to Greg Kroah-HartmanFrom: Ben Hutchings <[email protected]>
commit fb27e70f6e408dee5d22b083e7a38a59e6118253 upstream.
modpost now reads CRCs from .*.cmd files, parsing them using strtol(). This is inconsistent with its parsing of Module.symvers and with their definition as *unsigned* 32-bit values.
strtol() clamps values to [LONG_MIN, LONG_MAX], and when building on a 32-bit system this changes all CRCs >= 0x80000000 to be 0x7fffffff.
Change extract_crcs_for_object() to use strtoul() instead.
--- scripts/mod/modpost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/mod/modpost.c +1 -1
@@ -1722,7 +1722,7 @@ static void extract_crcs_for_object(consif (!isdigit (*p))continue ;/* skip this line */ - crc =strtol (p, &p,0 ); + crc =strtoul (p, &p,0 );if (*p !='\n' )continue ;/* skip this line */
Greg Kroah-Hartman
maintainerPATCH 145/181 pinctrl: amd: Disable and mask interrupts on resume
In reply to Greg Kroah-HartmanFrom: Kornel Dulęba <[email protected]>
commit b26cd9325be4c1fcd331b77f10acb627c560d4d7 upstream.
This fixes a similar problem to the one observed in:
commit 4e5a04be88fe ("pinctrl: amd: disable and mask interrupts on probe").
On some systems, during suspend/resume cycle firmware leaves an interrupt enabled on a pin that is not used by the kernel. This confuses the AMD pinctrl driver and causes spurious interrupts.
The driver already has logic to detect if a pin is used by the kernel. Leverage it to re-initialize interrupt fields of a pin only if it's not used by us.
--- drivers/pinctrl/pinctrl-amd.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-)
drivers/pinctrl/pinctrl-amd.c +20 -16
@@ -865,32 +865,34 @@ static const struct pinconf_ops amd_pinc .pin_config_group_set = amd_pinconf_group_set, }; -static void amd_gpio_irq_init (struct amd_gpio *gpio_dev) +static void amd_gpio_irq_init_pin (struct amd_gpio *gpio_dev,int pin) { -struct pinctrl_desc *desc = gpio_dev->pctrl->desc; +const struct pin_desc *pd;unsigned long flags;u32 pin_reg, mask; -int i; mask =BIT (WAKE_CNTRL_OFF_S0I3 ) |BIT (WAKE_CNTRL_OFF_S3 ) |BIT (INTERRUPT_MASK_OFF ) |BIT (INTERRUPT_ENABLE_OFF ) |BIT (WAKE_CNTRL_OFF_S4 ); -for (i =0 ; i < desc->npins; i++) { -int pin = desc->pins[i].number; -const struct pin_desc *pd =pin_desc_get (gpio_dev->pctrl, pin); - -if (!pd) -continue ; + pd =pin_desc_get (gpio_dev->pctrl, pin); +if (!pd) +return ; -raw_spin_lock_irqsave (&gpio_dev->lock, flags); +raw_spin_lock_irqsave (&gpio_dev->lock, flags); + pin_reg =readl (gpio_dev->base + pin *4 ); + pin_reg &= ~mask; +writel (pin_reg, gpio_dev->base + pin *4 ); +raw_spin_unlock_irqrestore (&gpio_dev->lock, flags); +} - pin_reg =readl (gpio_dev->base + i *4 ); - pin_reg &= ~mask; -writel (pin_reg, gpio_dev->base + i *4 ); +static void amd_gpio_irq_init (struct amd_gpio *gpio_dev) +{ +struct pinctrl_desc *desc = gpio_dev->pctrl->desc; +int i; -raw_spin_unlock_irqrestore (&gpio_dev->lock, flags); - } +for (i =0 ; i < desc->npins; i++) +amd_gpio_irq_init_pin (gpio_dev, i); }#ifdef CONFIG_PM_SLEEP
@@ -943,8 +945,10 @@ static int amd_gpio_resume(struct devicefor (i =0 ; i < desc->npins; i++) {int pin = desc->pins[i].number; -if (!amd_gpio_should_save (gpio_dev, pin)) +if (!amd_gpio_should_save (gpio_dev, pin)) { +amd_gpio_irq_init_pin (gpio_dev, pin);continue ; + }raw_spin_lock_irqsave (&gpio_dev->lock, flags); gpio_dev->saved_regs[i] |=readl (gpio_dev->base + pin *4 ) &PIN_IRQ_PENDING ;
Greg Kroah-Hartman
maintainerPATCH 146/181 pinctrl: at91-pio4: fix domain name assignment
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 7bb97e360acdd38b68ad0a1defb89c6e89c85596 upstream.
Since commit d59f6617eef0 ("genirq: Allow fwnode to carry name information only") an IRQ domain is always given a name during allocation (e.g. used for the debugfs entry).
Drop the no longer valid name assignment, which would lead to an attempt to free a string constant when removing the domain on late probe failures (e.g. probe deferral).
--- drivers/pinctrl/pinctrl-at91-pio4.c | 1 - 1 file changed, 1 deletion(-)
drivers/pinctrl/pinctrl-at91-pio4.c +0 -1
@@ -1176,7 +1176,6 @@ static int atmel_pinctrl_probe(struct pldev_err (dev,"can't add the irq domain\n" );return -ENODEV ; } - atmel_pioctrl->irq_domain->name ="atmel gpio" ;for (i =0 ; i < atmel_pioctrl->npins; i++) {int irq =irq_create_mapping (atmel_pioctrl->irq_domain, i);
Greg Kroah-Hartman
maintainerPATCH 147/181 platform/x86: ideapad-laptop: Stop sending KEY_TOUCHPAD_TOGGLE
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
commit e3271a5917d1501089b1a224d702aa053e2877f4 upstream.
Commit 5829f8a897e4 ("platform/x86: ideapad-laptop: Send KEY_TOUCHPAD_TOGGLE on some models") made ideapad-laptop send KEY_TOUCHPAD_TOGGLE when we receive an ACPI notify with VPC event bit 5 set and the touchpad-state has not been changed by the EC itself already.
This was done under the assumption that this would be good to do to make the touchpad-toggle hotkey work on newer models where the EC does not toggle the touchpad on/off itself (because it is not routed through the PS/2 controller, but uses I2C).
But it turns out that at least some models, e.g. the Yoga 7-15ITL5 the EC triggers an ACPI notify with VPC event bit 5 set on resume, which would now cause a spurious KEY_TOUCHPAD_TOGGLE on resume to which the desktop environment responds by disabling the touchpad in software, breaking the touchpad (until manually re-enabled) on resume.
It was never confirmed that sending KEY_TOUCHPAD_TOGGLE actually improves things on new models and at least some new models like the Yoga 7-15ITL5 don't have a touchpad on/off toggle hotkey at all, while still sending ACPI notify events with VPC event bit 5 set.
So it seems best to revert the change to send KEY_TOUCHPAD_TOGGLE when receiving an ACPI notify events with VPC event bit 5 and the touchpad state as reported by the EC has not changed.
Note this is not a full revert the code to cache the last EC touchpad state is kept to avoid sending spurious KEY_TOUCHPAD_ON / _OFF events on resume.
--- drivers/platform/x86/ideapad-laptop.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-)
drivers/platform/x86/ideapad-laptop.c +10 -13
@@ -1164,7 +1164,6 @@ static const struct key_entry ideapad_ke { KE_KEY, 65, { KEY_PROG4 } }, { KE_KEY, 66, { KEY_TOUCHPAD_OFF } }, { KE_KEY, 67, { KEY_TOUCHPAD_ON } }, - { KE_KEY, 68, { KEY_TOUCHPAD_TOGGLE } }, { KE_KEY, 128, { KEY_ESC } },/*
@@ -1520,18 +1519,16 @@ static void ideapad_sync_touchpad_state(if (priv->features.ctrl_ps2_aux_port)i8042_command (¶m, value ?I8042_CMD_AUX_ENABLE :I8042_CMD_AUX_DISABLE ); -if (send_events) { -/* -* On older models the EC controls the touchpad and toggles it -* on/off itself, in this case we report KEY_TOUCHPAD_ON/_OFF. -* If the EC did not toggle, report KEY_TOUCHPAD_TOGGLE. -*/ -if (value != priv->r_touchpad_val) { -ideapad_input_report (priv, value ?67 :66 ); -sysfs_notify (&priv->platform_device->dev.kobj,NULL ,"touchpad" ); - }else { -ideapad_input_report (priv,68 ); - } +/* +* On older models the EC controls the touchpad and toggles it on/off +* itself, in this case we report KEY_TOUCHPAD_ON/_OFF. Some models do +* an acpi-notify with VPC bit 5 set on resume, so this function get +* called with send_events=true on every resume. Therefor if the EC did +* not toggle, do nothing to avoid sending spurious KEY_TOUCHPAD_TOGGLE. +*/ +if (send_events && value != priv->r_touchpad_val) { +ideapad_input_report (priv, value ?67 :66 ); +sysfs_notify (&priv->platform_device->dev.kobj,NULL ,"touchpad" ); } priv->r_touchpad_val = value;
Greg Kroah-Hartman
maintainerPATCH 148/181 powerpc: Dont try to copy PPR for task with NULL pt_regs
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit fd7276189450110ed835eb0a334e62d2f1c4e3be upstream.
powerpc sets up PF_KTHREAD and PF_IO_WORKER with a NULL pt_regs, which from my (arguably very short) checking is not commonly done for other archs. This is fine, except when PF_IO_WORKER's have been created and the task does something that causes a coredump to be generated. Then we get this crash:
Kernel attempted to read user page (160) - exploit attempt? (uid: 1000)
BUG: Kernel NULL pointer dereference on read at 0x00000160
Faulting instruction address: 0xc0000000000c3a60
Oops: Kernel access of bad area, sig: 11 [#1]
LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=32 NUMA pSeries
Modules linked in: bochs drm_vram_helper drm_kms_helper xts binfmt_misc ecb ctr syscopyarea sysfillrect cbc sysimgblt drm_ttm_helper aes_generic ttm sg libaes evdev joydev virtio_balloon vmx_crypto gf128mul drm dm_mod fuse loop configfs drm_panel_orientation_quirks ip_tables x_tables autofs4 hid_generic usbhid hid xhci_pci xhci_hcd usbcore usb_common sd_mod
CPU: 1 PID: 1982 Comm: ppc-crash Not tainted 6.3.0-rc2+ #88
Hardware name: IBM pSeries (emulated by qemu) POWER9 (raw) 0x4e1202 0xf000005 of:SLOF,HEAD hv:linux,kvm pSeries
NIP: c0000000000c3a60 LR: c000000000039944 CTR: c0000000000398e0
REGS: c0000000041833b0 TRAP: 0300 Not tainted (6.3.0-rc2+)
MSR: 800000000280b033 <SF,VEC,VSX,EE,FP,ME,IR,DR,RI,LE> CR: 88082828 XER: 200400f8
...
NIP memcpy_power7+0x200/0x7d0
LR ppr_get+0x64/0xb0
Call Trace:
ppr_get+0x40/0xb0 (unreliable)
__regset_get+0x180/0x1f0
regset_get_alloc+0x64/0x90
elf_core_dump+0xb98/0x1b60
do_coredump+0x1c34/0x24a0
get_signal+0x71c/0x1410
do_notify_resume+0x140/0x6f0
interrupt_exit_user_prepare_main+0x29c/0x320
interrupt_exit_user_prepare+0x6c/0xa0
interrupt_return_srr_user+0x8/0x138Because ppr_get() is trying to copy from a PF_IO_WORKER with a NULL pt_regs.
Check for a valid pt_regs in both ppc_get/ppr_set, and return an error if not set. The actual error value doesn't seem to be important here, so just pick -EINVAL.
--- arch/powerpc/kernel/ptrace/ptrace-view.c | 6 ++++++ 1 file changed, 6 insertions(+)
arch/powerpc/kernel/ptrace/ptrace-view.c +6 -0
@@ -290,6 +290,9 @@ static int gpr_set(struct task_struct *tstatic int ppr_get (struct task_struct *target,const struct user_regset *regset,struct membuf to) { +if (!target->thread.regs) +return -EINVAL ; +return membuf_write (&to, &target->thread.regs->ppr,sizeof (u64)); }
@@ -297,6 +300,9 @@ static int ppr_set(struct task_struct *t unsigned int pos, unsigned int count, const void *kbuf, const void __user *ubuf) { + if (!target->thread.regs) + return -EINVAL; + return user_regset_copyin(&pos, &count, &kbuf, &ubuf, &target->thread.regs->ppr, 0, sizeof(u64)); }
Greg Kroah-Hartman
maintainerPATCH 149/181 powerpc/pseries/vas: Ignore VAS update for DLPAR if copy/paste is not enabled
In reply to Greg Kroah-HartmanFrom: Haren Myneni <[email protected]>
commit eca9f6e6f83b6725b84e1c76fdde19b003cff0eb upstream.
The hypervisor supports user-mode NX from Power10.
pseries_vas_dlpar_cpu() is called from lparcfg_write() to update VAS windows for DLPAR event in shared processor mode and the kernel gets -ENOTSUPP for HCALLs if the user-mode NX is not supported. The current VAS implementation also supports only with Radix page tables. Whereas in dedicated processor mode, pseries_vas_notifier() is registered only if the copy/paste feature is enabled. So instead of displaying HCALL error messages, update VAS capabilities if the copy/paste feature is available.
This patch ignores updating VAS capabilities in pseries_vas_dlpar_cpu() and returns success if the copy/paste feature is not enabled. Then lparcfg_write() completes the processor DLPAR operations without any failures.
--- arch/powerpc/platforms/pseries/vas.c | 8 ++++++++ 1 file changed, 8 insertions(+)
arch/powerpc/platforms/pseries/vas.c +8 -0
@@ -857,6 +857,13 @@ int pseries_vas_dlpar_cpu(void) {int new_nr_creds, rc; +/* +* NX-GZIP is not enabled. Nothing to do for DLPAR event +*/ +if (!copypaste_feat) +return 0 ; + + rc =h_query_vas_capabilities (H_QUERY_VAS_CAPABILITIES , vascaps[VAS_GZIP_DEF_FEAT_TYPE ].feat, (u64 )virt_to_phys (&hv_cop_caps));
@@ -1013,6 +1020,7 @@ static int __init pseries_vas_init(void)* Linux supports user space COPY/PASTE only with Radix */ if (!radix_enabled ()) { + copypaste_feat = false;pr_err ("API is supported only with radix page tables\n" );return -ENOTSUPP ; }
Greg Kroah-Hartman
maintainerPATCH 150/181 powerpc/64s: Fix __pte_needs_flush() false positive warning
In reply to Greg Kroah-HartmanFrom: Benjamin Gray <[email protected]>
commit 1abce0580b89464546ae06abd5891ebec43c9470 upstream.
Userspace PROT_NONE ptes set _PAGE_PRIVILEGED, triggering a false positive debug assertion that __pte_flags_need_flush() is not called on a kernel mapping.
Detect when it is a userspace PROT_NONE page by checking the required bits of PAGE_NONE are set, and none of the RWX bits are set. pte_protnone() is insufficient here because it always returns 0 when CONFIG_NUMA_BALANCING=n.
--- arch/powerpc/include/asm/book3s/64/tlbflush.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
arch/powerpc/include/asm/book3s/64/tlbflush.h +7 -2
@@ -163,6 +163,11 @@ static inline void flush_tlb_fix_spuriou*/ } +static inline bool __pte_protnone (unsigned long pte) +{ +return (pte & (pgprot_val (PAGE_NONE ) | _PAGE_RWX)) ==pgprot_val (PAGE_NONE ); +} +static inline bool __pte_flags_need_flush (unsigned long oldval,unsigned long newval) {
@@ -179,8 +184,8 @@ static inline bool __pte_flags_need_flus/* * We do not expect kernel mappings or non-PTEs or not-present PTEs. */ -VM_WARN_ON_ONCE (oldval & _PAGE_PRIVILEGED); -VM_WARN_ON_ONCE (newval & _PAGE_PRIVILEGED); +VM_WARN_ON_ONCE (!__pte_protnone (oldval) && oldval & _PAGE_PRIVILEGED); +VM_WARN_ON_ONCE (!__pte_protnone (newval) && newval & _PAGE_PRIVILEGED);VM_WARN_ON_ONCE (!(oldval & _PAGE_PTE));VM_WARN_ON_ONCE (!(newval & _PAGE_PTE));VM_WARN_ON_ONCE (!(oldval & _PAGE_PRESENT));
Greg Kroah-Hartman
maintainerPATCH 151/181 NFSv4: Fix hangs when recovering open state after a server reboot
In reply to Greg Kroah-HartmanFrom: Trond Myklebust <[email protected]>
commit 6165a16a5ad9b237bb3131cff4d3c601ccb8f9a3 upstream.
When we're using a cached open stateid or a delegation in order to avoid sending a CLAIM_PREVIOUS open RPC call to the server, we don't have a new open stateid to present to update_open_stateid(). Instead rely on nfs4_try_open_cached(), just as if we were doing a normal open.
--- fs/nfs/nfs4proc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
fs/nfs/nfs4proc.c +2 -3
@@ -1980,8 +1980,7 @@ _nfs4_opendata_reclaim_to_nfs4_state(strif (!data->rpc_done) {if (data->rpc_status)return ERR_PTR (data->rpc_status); -/* cached opens have already been processed */ - goto update; +return nfs4_try_open_cached (data); } ret =nfs_refresh_inode (inode, &data->f_attr);
@@ -1990,7 +1989,7 @@ _nfs4_opendata_reclaim_to_nfs4_state(strif (data->o_res.delegation_type !=0 )nfs4_opendata_check_deleg (data, state); -update: +if (!update_open_stateid (state, &data->o_res.stateid,NULL , data->o_arg.fmode))return ERR_PTR (-EAGAIN );
Greg Kroah-Hartman
maintainerPATCH 152/181 ALSA: hda/conexant: Partial revert of a quirk for Lenovo
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit b871cb971c683f7f212e7ca3c9a6709a75785116 upstream.
The recent commit f83bb2592482 ("ALSA: hda/conexant: Add quirk for LENOVO 20149 Notebook model") introduced a quirk for the device with 17aa:3977, but this caused a regression on another model (Lenovo Ideadpad U31) with the very same PCI SSID. And, through skimming over the net, it seems that this PCI SSID is used for multiple different models, so it's no good idea to apply the quirk with the SSID.
Although we may take a different ID check (e.g. the codec SSID instead of the PCI SSID), unfortunately, the original patch author couldn't identify the hardware details any longer as the machine was returned, and we can't develop the further proper fix.
In this patch, instead, we partially revert the change so that the quirk won't be applied as default for addressing the regression. Meanwhile, the quirk function itself is kept, and it's now made to be applicable via the explicit model=lenovo-20149 option.
--- sound/pci/hda/patch_conexant.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
sound/pci/hda/patch_conexant.c +5 -1
@@ -980,7 +980,10 @@ static const struct snd_pci_quirk cxt506SND_PCI_QUIRK (0x17aa ,0x3905 ,"Lenovo G50-30" ,CXT_FIXUP_STEREO_DMIC ),SND_PCI_QUIRK (0x17aa ,0x390b ,"Lenovo G50-80" ,CXT_FIXUP_STEREO_DMIC ),SND_PCI_QUIRK (0x17aa ,0x3975 ,"Lenovo U300s" ,CXT_FIXUP_STEREO_DMIC ), -SND_PCI_QUIRK (0x17aa ,0x3977 ,"Lenovo IdeaPad U310" ,CXT_PINCFG_LENOVO_NOTEBOOK ), +/* NOTE: we'd need to extend the quirk for 17aa:3977 as the same +* PCI SSID is used on multiple Lenovo models +*/ +SND_PCI_QUIRK (0x17aa ,0x3977 ,"Lenovo IdeaPad U310" ,CXT_FIXUP_STEREO_DMIC ),SND_PCI_QUIRK (0x17aa ,0x3978 ,"Lenovo G50-70" ,CXT_FIXUP_STEREO_DMIC ),SND_PCI_QUIRK (0x17aa ,0x397b ,"Lenovo S205" ,CXT_FIXUP_STEREO_DMIC ), SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", CXT_FIXUP_THINKPAD_ACPI),
@@ -1003,6 +1006,7 @@ static const struct hda_model_fixup cxt5 { .id = CXT_FIXUP_MUTE_LED_GPIO, .name = "mute-led-gpio" }, { .id = CXT_FIXUP_HP_ZBOOK_MUTE_LED, .name = "hp-zbook-mute-led" }, { .id = CXT_FIXUP_HP_MIC_NO_PRESENCE, .name = "hp-mic-fix" }, + { .id = CXT_PINCFG_LENOVO_NOTEBOOK, .name = "lenovo-20149" }, {} };
Greg Kroah-Hartman
maintainerPATCH 153/181 ALSA: usb-audio: Fix regression on detection of Roland VS-100
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit fa4e7a6fa12b1132340785e14bd439cbe95b7a5a upstream.
It's been reported that the recent kernel can't probe the PCM devices on Roland VS-100 properly, and it turned out to be a regression by the recent addition of the bit shift range check for the format bits. In the old code, we just did bit-shift and it resulted in zero, which is then corrected to the standard PCM format, while the new code explicitly returns an error in such a case.
For addressing the regression, relax the check and fallback to the standard PCM type (with the info output).
--- sound/usb/format.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
sound/usb/format.c +6 -2
@@ -39,8 +39,12 @@ static u64 parse_audio_format_i_type(strcase UAC_VERSION_1 :default : {struct uac_format_type_i_discrete_descriptor *fmt = _fmt; -if (format >=64 ) -return 0 ;/* invalid format */ +if (format >=64 ) { +usb_audio_info (chip, +"%u:%d: invalid format type 0x%llx is detected, processed as PCM\n" , + fp->iface, fp->altsetting, format); + format =UAC_FORMAT_TYPE_I_PCM ; + } sample_width = fmt->bBitResolution; sample_bytes = fmt->bSubframeSize; format =1ULL << format;
Greg Kroah-Hartman
maintainerPATCH 154/181 ALSA: hda/realtek: Add quirks for some Clevo laptops
In reply to Greg Kroah-HartmanFrom: Tim Crawford <[email protected]>
commit b7a5822810c4398515300d614d988cf638adecad upstream.
Add the audio quirk for some of Clevo's latest RPL laptops:
- NP50RNJS (ALC256)
- NP70SNE (ALC256)
- PD50SNE (ALC1220)
- PE60RNE (ALC1220)
--- sound/pci/hda/patch_realtek.c | 4 ++++ 1 file changed, 4 insertions(+)
sound/pci/hda/patch_realtek.c +4 -0
@@ -2631,6 +2631,7 @@ static const struct snd_pci_quirk alc882SND_PCI_QUIRK (0x1558 ,0x65e5 ,"Clevo PC50D[PRS](?:-D|-G)?" ,ALC1220_FIXUP_CLEVO_PB51ED_PINS ),SND_PCI_QUIRK (0x1558 ,0x65f1 ,"Clevo PC50HS" ,ALC1220_FIXUP_CLEVO_PB51ED_PINS ),SND_PCI_QUIRK (0x1558 ,0x65f5 ,"Clevo PD50PN[NRT]" ,ALC1220_FIXUP_CLEVO_PB51ED_PINS ), +SND_PCI_QUIRK (0x1558 ,0x66a2 ,"Clevo PE60RNE" ,ALC1220_FIXUP_CLEVO_PB51ED_PINS ),SND_PCI_QUIRK (0x1558 ,0x67d1 ,"Clevo PB71[ER][CDF]" ,ALC1220_FIXUP_CLEVO_PB51ED_PINS ),SND_PCI_QUIRK (0x1558 ,0x67e1 ,"Clevo PB71[DE][CDF]" ,ALC1220_FIXUP_CLEVO_PB51ED_PINS ), SND_PCI_QUIRK(0x1558, 0x67e5, "Clevo PC70D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
@@ -2651,6 +2652,7 @@ static const struct snd_pci_quirk alc882SND_PCI_QUIRK (0x1558 ,0x96e1 ,"Clevo P960[ER][CDFN]-K" ,ALC1220_FIXUP_CLEVO_P950 ),SND_PCI_QUIRK (0x1558 ,0x97e1 ,"Clevo P970[ER][CDFN]" ,ALC1220_FIXUP_CLEVO_P950 ),SND_PCI_QUIRK (0x1558 ,0x97e2 ,"Clevo P970RC-M" ,ALC1220_FIXUP_CLEVO_P950 ), +SND_PCI_QUIRK (0x1558 ,0xd502 ,"Clevo PD50SNE" ,ALC1220_FIXUP_CLEVO_PB51ED_PINS ),SND_PCI_QUIRK_VENDOR (0x1558 ,"Clevo laptop" ,ALC882_FIXUP_EAPD ),SND_PCI_QUIRK (0x161f ,0x2054 ,"Medion laptop" ,ALC883_FIXUP_EAPD ), SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
@@ -9574,6 +9576,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x1558 ,0x5101 ,"Clevo S510WU" ,ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1558 ,0x5157 ,"Clevo W517GU1" ,ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1558 ,0x51a1 ,"Clevo NS50MU" ,ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE ), +SND_PCI_QUIRK (0x1558 ,0x5630 ,"Clevo NP50RNJS" ,ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1558 ,0x70a1 ,"Clevo NB70T[HJK]" ,ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1558 ,0x70b3 ,"Clevo NK70SB" ,ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE ), SND_PCI_QUIRK(0x1558, 0x70f2, "Clevo NH79EPY", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
@@ -9608,6 +9611,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x1558 ,0x971d ,"Clevo N970T[CDF]" ,ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1558 ,0xa500 ,"Clevo NL5[03]RU" ,ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1558 ,0xa600 ,"Clevo NL50NU" ,ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE ), +SND_PCI_QUIRK (0x1558 ,0xa671 ,"Clevo NP70SN[CDE]" ,ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1558 ,0xb018 ,"Clevo NP50D[BE]" ,ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1558 ,0xb019 ,"Clevo NH77D[BE]Q" ,ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE ), SND_PCI_QUIRK(0x1558, 0xb022, "Clevo NH77D[DC][QW]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Greg Kroah-Hartman
maintainerPATCH 155/181 ALSA: hda/realtek: Add quirk for Lenovo ZhaoYang CF4620Z
In reply to Greg Kroah-HartmanFrom: huangwenhui <[email protected]>
commit 52aad39385e1bfdb34a1b405f699a8ef302c58b0 upstream.
Fix headset microphone detection on Lenovo ZhaoYang CF4620Z.
[ adjusted to be applicable to the latest tree -- tiwai ]
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -9712,6 +9712,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x17aa ,0x511e ,"Thinkpad" ,ALC298_FIXUP_TPT470_DOCK ),SND_PCI_QUIRK (0x17aa ,0x511f ,"Thinkpad" ,ALC298_FIXUP_TPT470_DOCK ),SND_PCI_QUIRK (0x17aa ,0x9e54 ,"LENOVO NB" ,ALC269_FIXUP_LENOVO_EAPD ), +SND_PCI_QUIRK (0x17aa ,0x9e56 ,"Lenovo ZhaoYang CF4620Z" ,ALC286_FIXUP_SONY_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1849 ,0x1233 ,"ASRock NUC Box 1100" ,ALC233_FIXUP_NO_AUDIO_JACK ),SND_PCI_QUIRK (0x1849 ,0xa233 ,"Positivo Master C6300" ,ALC269_FIXUP_HEADSET_MIC ), SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
Greg Kroah-Hartman
maintainerPATCH 156/181 xtensa: fix KASAN report for show_stack
In reply to Greg Kroah-HartmanFrom: Max Filippov <[email protected]>
commit 1d3b7a788ca7435156809a6bd5b20c95b2370d45 upstream.
show_stack dumps raw stack contents which may trigger an unnecessary KASAN report. Fix it by copying stack contents to a temporary buffer with __memcpy and then printing that buffer instead of passing stack pointer directly to the print_hex_dump.
--- arch/xtensa/kernel/traps.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
arch/xtensa/kernel/traps.c +12 -4
@@ -541,7 +541,7 @@ static size_t kstack_depth_to_print = COvoid show_stack (struct task_struct *task,unsigned long *sp,const char *loglvl) { -size_t len; +size_t len, off =0 ;if (!sp) sp =stack_pointer (task);
@@ -550,9 +550,17 @@ void show_stack(struct task_struct *task kstack_depth_to_print * STACK_DUMP_ENTRY_SIZE);printk ("%sStack:\n" , loglvl); -print_hex_dump (loglvl," " ,DUMP_PREFIX_NONE , -STACK_DUMP_LINE_SIZE ,STACK_DUMP_ENTRY_SIZE , - sp, len, false); +while (off < len) { +u8 line[STACK_DUMP_LINE_SIZE ]; +size_t line_len = len - off >STACK_DUMP_LINE_SIZE ? +STACK_DUMP_LINE_SIZE : len - off; + +__memcpy (line, (u8 *)sp + off, line_len); +print_hex_dump (loglvl," " ,DUMP_PREFIX_NONE , +STACK_DUMP_LINE_SIZE ,STACK_DUMP_ENTRY_SIZE , + line, line_len, false); + off +=STACK_DUMP_LINE_SIZE ; + }show_trace (task, sp, loglvl); }
Greg Kroah-Hartman
maintainerPATCH 157/181 rcu: Fix rcu_torture_read ftrace event
In reply to Greg Kroah-HartmanFrom: Douglas Raillard <[email protected]>
commit d18a04157fc171fd48075e3dc96471bd3b87f0dd upstream.
Fix the rcutorturename field so that its size is correctly reported in the text format embedded in trace.dat files. As it stands, it is reported as being of size 1:
field:char rcutorturename[8]; offset:8; size:1; signed:0;
--- include/trace/events/rcu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/trace/events/rcu.h +1 -1
@@ -768,7 +768,7 @@ TRACE_EVENT_RCU(rcu_torture_read,TP_ARGS (rcutorturename, rhp, secs, c_old, c),TP_STRUCT__entry ( - __field(char, rcutorturename[RCUTORTURENAME_LEN]) + __array(char, rcutorturename, RCUTORTURENAME_LEN) __field(struct rcu_head *, rhp) __field(unsigned long, secs) __field(unsigned long, c_old)
Greg Kroah-Hartman
maintainerPATCH 158/181 dt-bindings: mtd: jedec,spi-nor: Document CPOL/CPHA support
In reply to Greg Kroah-HartmanFrom: Geert Uytterhoeven <[email protected]>
commit a56cde41340ac4049fa6edac9e6cfbcd2804074e upstream.
SPI EEPROMs typically support both SPI Mode 0 (CPOL=CPHA=0) and Mode 3 (CPOL=CPHA=1). However, using the latter is currently flagged as an error by "make dtbs_check", e.g.:
arch/arm/boot/dts/r8a7791-koelsch.dtb: flash@0: Unevaluated properties are not allowed ('spi-cpha', 'spi-cpol' were unexpected)
From schema: Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
Fix this by documenting support for CPOL=CPHA=1.
--- Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml | 7 +++++++ 1 file changed, 7 insertions(+)
Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml +7 -0
@@ -84,6 +84,13 @@ patternProperties: "^otp(-[0-9]+)?$": type: object + spi-cpol: true + spi-cpha: true + +dependencies: + spi-cpol: [ spi-cpha ] + spi-cpha: [ spi-cpol ] + unevaluatedProperties: false examples:
Greg Kroah-Hartman
maintainerPATCH 159/181 s390/uaccess: add missing earlyclobber annotations to __clear_user()
In reply to Greg Kroah-HartmanFrom: Heiko Carstens <[email protected]>
commit 89aba4c26fae4e459f755a18912845c348ee48f3 upstream.
Add missing earlyclobber annotation to size, to, and tmp2 operands of the __clear_user() inline assembly since they are modified or written to before the last usage of all input operands. This can lead to incorrect register allocation for the inline assembly.
--- arch/s390/lib/uaccess.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/s390/lib/uaccess.c +1 -1
@@ -172,7 +172,7 @@ unsigned long __clear_user(void __user *"4: slgr %0,%0\n" "5:\n" EX_TABLE(0b,2b) EX_TABLE(6b,2b) EX_TABLE(3b,5b) EX_TABLE(7b,5b) - : "+a" (size), "+a" (to), "+a" (tmp1), "=a" (tmp2) + : "+&a" (size), "+&a" (to), "+a" (tmp1), "=&a" (tmp2) : "a" (empty_zero_page), [spec] "d" (spec.val) : "cc", "memory", "0");return size;
Greg Kroah-Hartman
maintainerPATCH 160/181 s390: reintroduce expoline dependence to scripts
In reply to Greg Kroah-HartmanFrom: Jiri Slaby (SUSE) <[email protected]>
commit 7bb2107e63d8a4a13bbb6fe0e1cbd68784a2e9ac upstream.
Expolines depend on scripts/basic/fixdep. And build of expolines can now race with the fixdep build:
make[1]: *** Deleting file 'arch/s390/lib/expoline/expoline.o'
/bin/sh: line 1: scripts/basic/fixdep: Permission denied
make[1]: *** [../scripts/Makefile.build:385: arch/s390/lib/expoline/expoline.o] Error 126
make: *** [../arch/s390/Makefile:166: expoline_prepare] Error 2
The dependence was removed in the below Fixes: commit. So reintroduce the dependence on scripts.
--- arch/s390/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/s390/Makefile +1 -1
@@ -162,7 +162,7 @@ vdso_prepare: prepare0 ifdef CONFIG_EXPOLINE_EXTERN modules_prepare: expoline_prepare -expoline_prepare: +expoline_prepare: scripts $(Q)$(MAKE) $(build)=arch/s390/lib/expoline arch/s390/lib/expoline/expoline.o endif endif
Greg Kroah-Hartman
maintainerPATCH 161/181 drm/etnaviv: fix reference leak when mmaping imported buffer
In reply to Greg Kroah-HartmanFrom: Lucas Stach <[email protected]>
commit 963b2e8c428f79489ceeb058e8314554ec9cbe6f upstream.
drm_gem_prime_mmap() takes a reference on the GEM object, but before that drm_gem_mmap_obj() already takes a reference, which will be leaked as only one reference is dropped when the mapping is closed. Drop the extra reference when dma_buf_mmap() succeeds.
--- drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c +9 -1
@@ -91,7 +91,15 @@ static void *etnaviv_gem_prime_vmap_implstatic int etnaviv_gem_prime_mmap_obj (struct etnaviv_gem_object *etnaviv_obj,struct vm_area_struct *vma) { -return dma_buf_mmap (etnaviv_obj->base.dma_buf, vma,0 ); +int ret; + + ret =dma_buf_mmap (etnaviv_obj->base.dma_buf, vma,0 ); +if (!ret) { +/* Drop the reference acquired by drm_gem_mmap_obj(). */ +drm_gem_object_put (&etnaviv_obj->base); + } + +return ret; }static const struct etnaviv_gem_ops etnaviv_gem_prime_ops = {
Greg Kroah-Hartman
maintainerPATCH 162/181 drm/amdgpu: allow more APUs to do mode2 reset when go to S4
In reply to Greg Kroah-HartmanFrom: Tim Huang <[email protected]>
commit 2fec9dc8e0acc3dfb56d1389151bcf405f087b10 upstream.
Skip mode2 reset only for IMU enabled APUs when do S4.
This patch is to fix the regression issue
https://gitlab.freedesktop.org/drm/amd/-/issues/2483
It is generated by commit b589626674de ("drm/amdgpu: skip ASIC reset for APUs when go to S4").
--- drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +6 -1
@@ -981,7 +981,12 @@ static bool amdgpu_atcs_pci_probe_handle(struct pci_dev *pdev)*/ bool amdgpu_acpi_should_gpu_reset (struct amdgpu_device *adev) { -if (adev->flags &AMD_IS_APU ) +if ((adev->flags &AMD_IS_APU ) && + adev->gfx.imu.funcs)/* Not need to do mode2 reset for IMU enabled APUs */ +return false; + +if ((adev->flags &AMD_IS_APU ) && +amdgpu_acpi_is_s3_active (adev))return false;if (amdgpu_sriov_vf (adev))
Signature · 1 line
2.40.0
Greg Kroah-Hartman
maintainerPATCH 163/181 drm/amd/display: Add DSC Support for Synaptics Cascaded MST Hub
In reply to Greg Kroah-HartmanFrom: Fangzhi Zuo <[email protected]>
commit f4f3b7dedbe849e780c779ba67365bb1db0d8637 upstream.
Traditional synaptics hub has one MST branch device without virtual dpcd. Synaptics cascaded hub has two chained MST branch devices. DSC decoding is performed via root MST branch device, instead of the second MST branch device.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 19 ++++++++++++ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h | 12 +++++++ 2 files changed, 31 insertions(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +19 -0
@@ -208,6 +208,21 @@ bool needs_dsc_aux_workaround(struct dc_return false; } +bool is_synaptics_cascaded_panamera (struct dc_link *link,struct drm_dp_mst_port *port) +{ +u8 branch_vendor_data[4 ] = {0 };// Vendor data 0x50C ~ 0x50F + +if (drm_dp_dpcd_read (port->mgr->aux,DP_BRANCH_VENDOR_SPECIFIC_START , &branch_vendor_data,4 ) ==4 ) { +if (link->dpcd_caps.branch_dev_id ==DP_BRANCH_DEVICE_ID_90CC24 && +IS_SYNAPTICS_CASCADED_PANAMERA (link->dpcd_caps.branch_dev_name, branch_vendor_data)) { +DRM_INFO ("Synaptics Cascaded MST hub\n" ); +return true; + } + } + +return false; +} +static bool validate_dsc_caps_on_connector (struct amdgpu_dm_connector *aconnector) {struct dc_sink *dc_sink = aconnector->dc_sink;
@@ -231,6 +246,10 @@ static bool validate_dsc_caps_on_connect needs_dsc_aux_workaround(aconnector->dc_link)) aconnector->dsc_aux = &aconnector->mst_port->dm_dp_aux.aux; +/* synaptics cascaded MST hub case */ +if (!aconnector->dsc_aux &&is_synaptics_cascaded_panamera (aconnector->dc_link, port)) + aconnector->dsc_aux = port->mgr->aux; +if (!aconnector->dsc_aux)return false;
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h +12 -0
@@ -34,6 +34,18 @@#define SYNAPTICS_RC_OFFSET 0x4BC#define SYNAPTICS_RC_DATA 0x4C0 +#define DP_BRANCH_VENDOR_SPECIFIC_START 0x50C + +/** +* Panamera MST Hub detection +* Offset DPCD 050Eh == 0x5A indicates cascaded MST hub case +* Check from beginning of branch device vendor specific field (050Ch) +*/ +#define IS_SYNAPTICS_PANAMERA (branchDevName) (((int)branchDevName[4] & 0xF0) == 0x50 ? 1 : 0) +#define BRANCH_HW_REVISION_PANAMERA_A2 0x10 +#define SYNAPTICS_CASCADED_HUB_ID 0x5A +#define IS_SYNAPTICS_CASCADED_PANAMERA (devName, data) ((IS_SYNAPTICS_PANAMERA(devName) && ((int)data[2] == SYNAPTICS_CASCADED_HUB_ID)) ? 1 : 0) +struct amdgpu_display_manager ;struct amdgpu_dm_connector ;
Greg Kroah-Hartman
maintainerPATCH 164/181 drm/amd/display: Take FEC Overhead into Timeslot Calculation
In reply to Greg Kroah-HartmanFrom: Fangzhi Zuo <[email protected]>
commit 68dc1846c3a44d5e633be145c169ce2fd5420695 upstream.
8b/10b encoding needs to add 3% fec overhead into the pbn. In the Synapcis Cascaded MST hub, the first stage MST branch device needs the information to determine the timeslot count for the second stage MST branch device. Missing this overhead will leads to insufficient timeslot allocation.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 32 +++++++++--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h | 3 + 2 files changed, 27 insertions(+), 8 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +24 -8
@@ -646,12 +646,25 @@ struct dsc_mst_fairness_params {struct amdgpu_dm_connector *aconnector; }; -static int kbps_to_peak_pbn (int kbps) +static uint16_t get_fec_overhead_multiplier (struct dc_link *dc_link) +{ +u8 link_coding_cap; +uint16_t fec_overhead_multiplier_x1000 =PBN_FEC_OVERHEAD_MULTIPLIER_8B_10B ; + + link_coding_cap =dc_link_dp_mst_decide_link_encoding_format (dc_link); +if (link_coding_cap == DP_128b_132b_ENCODING) + fec_overhead_multiplier_x1000 =PBN_FEC_OVERHEAD_MULTIPLIER_128B_132B ; + +return fec_overhead_multiplier_x1000; +} + +static int kbps_to_peak_pbn (int kbps,uint16_t fec_overhead_multiplier_x1000) {u64 peak_kbps = kbps; peak_kbps *=1006 ; - peak_kbps =div_u64 (peak_kbps,1000 ); + peak_kbps *= fec_overhead_multiplier_x1000; + peak_kbps =div_u64 (peak_kbps,1000 *1000 );return (int )DIV64_U64_ROUND_UP (peak_kbps *64 , (54 *8 *1000 )); }
@@ -738,11 +751,12 @@ static int increase_dsc_bpp(struct drm_aint link_timeslots_used;int fair_pbn_alloc;int ret =0 ; +uint16_t fec_overhead_multiplier_x1000 =get_fec_overhead_multiplier (dc_link);for (i =0 ; i < count; i++) {if (vars[i + k].dsc_enabled) { initial_slack[i] = -kbps_to_peak_pbn (params[i].bw_range.max_kbps) - vars[i + k].pbn; +kbps_to_peak_pbn (params[i].bw_range.max_kbps, fec_overhead_multiplier_x1000) - vars[i + k].pbn; bpp_increased[i] = false; remaining_to_increase +=1 ; }else {
@@ -838,6 +852,7 @@ static int try_disable_dsc(struct drm_atint next_index;int remaining_to_try =0 ;int ret; +uint16_t fec_overhead_multiplier_x1000 =get_fec_overhead_multiplier (dc_link);for (i =0 ; i < count; i++) { if (vars[i + k].dsc_enabled
@@ -867,7 +882,7 @@ static int try_disable_dsc(struct drm_atif (next_index ==-1 )break ; - vars[next_index].pbn =kbps_to_peak_pbn (params[next_index].bw_range.stream_kbps); + vars[next_index].pbn =kbps_to_peak_pbn (params[next_index].bw_range.stream_kbps, fec_overhead_multiplier_x1000); ret = drm_dp_atomic_find_time_slots(state, params[next_index].port->mgr, params[next_index].port,
@@ -880,7 +895,7 @@ static int try_disable_dsc(struct drm_at vars[next_index].dsc_enabled = false; vars[next_index].bpp_x16 =0 ; }else { - vars[next_index].pbn =kbps_to_peak_pbn (params[next_index].bw_range.max_kbps); + vars[next_index].pbn =kbps_to_peak_pbn (params[next_index].bw_range.max_kbps, fec_overhead_multiplier_x1000); ret = drm_dp_atomic_find_time_slots(state, params[next_index].port->mgr, params[next_index].port,
@@ -909,6 +924,7 @@ static int compute_mst_dsc_configs_for_lint count =0 ;int i, k, ret;bool debugfs_overwrite = false; +uint16_t fec_overhead_multiplier_x1000 =get_fec_overhead_multiplier (dc_link);memset (params,0 ,sizeof (params));
@@ -970,7 +986,7 @@ static int compute_mst_dsc_configs_for_l/* Try no compression */ for (i =0 ; i < count; i++) { vars[i + k].aconnector = params[i].aconnector; - vars[i + k].pbn =kbps_to_peak_pbn (params[i].bw_range.stream_kbps); + vars[i + k].pbn =kbps_to_peak_pbn (params[i].bw_range.stream_kbps, fec_overhead_multiplier_x1000); vars[i + k].dsc_enabled = false; vars[i + k].bpp_x16 =0 ; ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr, params[i].port,
@@ -989,7 +1005,7 @@ static int compute_mst_dsc_configs_for_l/* Try max compression */ for (i =0 ; i < count; i++) {if (params[i].compression_possible && params[i].clock_force_enable !=DSC_CLK_FORCE_DISABLE ) { - vars[i + k].pbn =kbps_to_peak_pbn (params[i].bw_range.min_kbps); + vars[i + k].pbn =kbps_to_peak_pbn (params[i].bw_range.min_kbps, fec_overhead_multiplier_x1000); vars[i + k].dsc_enabled = true; vars[i + k].bpp_x16 = params[i].bw_range.min_target_bpp_x16; ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr,
@@ -997,7 +1013,7 @@ static int compute_mst_dsc_configs_for_lif (ret <0 )return ret; }else { - vars[i + k].pbn =kbps_to_peak_pbn (params[i].bw_range.stream_kbps); + vars[i + k].pbn =kbps_to_peak_pbn (params[i].bw_range.stream_kbps, fec_overhead_multiplier_x1000); vars[i + k].dsc_enabled = false; vars[i + k].bpp_x16 =0 ; ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr,
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h +3 -0
@@ -46,6 +46,9 @@#define SYNAPTICS_CASCADED_HUB_ID 0x5A#define IS_SYNAPTICS_CASCADED_PANAMERA (devName, data) ((IS_SYNAPTICS_PANAMERA(devName) && ((int)data[2] == SYNAPTICS_CASCADED_HUB_ID)) ? 1 : 0) +#define PBN_FEC_OVERHEAD_MULTIPLIER_8B_10B 1031 +#define PBN_FEC_OVERHEAD_MULTIPLIER_128B_132B 1000 +struct amdgpu_display_manager ;struct amdgpu_dm_connector ;
Greg Kroah-Hartman
maintainerPATCH 165/181 drm/i915/gem: Flush lmem contents after construction
In reply to Greg Kroah-HartmanFrom: Chris Wilson <[email protected]>
commit d032ca43f2c80049ce5aabd3f208dc3849359497 upstream.
i915_gem_object_create_lmem_from_data() lacks the flush of the data written to lmem to ensure the object is marked as dirty and the writes flushed to the backing store. Once created, we can immediately release the obj->mm.mapping caching of the vmap.
--- drivers/gpu/drm/i915/gem/i915_gem_lmem.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/gem/i915_gem_lmem.c +2 -1
@@ -127,7 +127,8 @@ i915_gem_object_create_lmem_from_data(stmemcpy (map, data, size); -i915_gem_object_unpin_map (obj); +i915_gem_object_flush_map (obj); +__i915_gem_object_release_map (obj);return obj; }
Greg Kroah-Hartman
maintainerPATCH 166/181 drm/i915/dpt: Treat the DPT BO as a framebuffer
In reply to Greg Kroah-HartmanFrom: Ville Syrjälä <[email protected]>
commit 3413881e1ecc3cba722a2e87ec099692eed5be28 upstream.
Currently i915_gem_object_is_framebuffer() doesn't treat the BO containing the framebuffer's DPT as a framebuffer itself. This means eg. that the shrinker can evict the DPT BO while leaving the actual FB BO bound, when the DPT is allocated from regular shmem.
That causes an immediate oops during hibernate as we try to rewrite the PTEs inside the already evicted DPT obj.
TODO: presumably this might also be the reason for the DPT related display faults under heavy memory pressure, but I'm still not sure how that would happen as the object should be pinned by intel_dpt_pin() while in active use by the display engine...
--- drivers/gpu/drm/i915/display/intel_dpt.c | 2 ++ drivers/gpu/drm/i915/gem/i915_gem_object.h | 2 +- drivers/gpu/drm/i915/gem/i915_gem_object_types.h | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/display/intel_dpt.c +2 -0
@@ -300,6 +300,7 @@ intel_dpt_create(struct intel_framebuffe vm->pte_encode = gen8_ggtt_pte_encode; dpt->obj = dpt_obj; + dpt->obj->is_dpt = true;return &dpt->vm; }
@@ -308,5 +309,6 @@ void intel_dpt_destroy(struct i915_addre {struct i915_dpt *dpt =i915_vm_to_dpt (vm); + dpt->obj->is_dpt = false;i915_vm_put (&dpt->vm); }
drivers/gpu/drm/i915/gem/i915_gem_object.h +1 -1
@@ -319,7 +319,7 @@ i915_gem_object_never_mmap(const structstatic inline bool i915_gem_object_is_framebuffer (const struct drm_i915_gem_object *obj) { -return READ_ONCE (obj->frontbuffer); +return READ_ONCE (obj->frontbuffer) || obj->is_dpt; } static inline unsigned int
drivers/gpu/drm/i915/gem/i915_gem_object_types.h +3 -0
@@ -491,6 +491,9 @@ struct drm_i915_gem_object {*/ unsigned int cache_dirty:1; +/* @is_dpt: Object houses a display page table (DPT) */ + unsigned int is_dpt:1; +/** * @read_domains: Read memory domains. *
Greg Kroah-Hartman
maintainerPATCH 167/181 drm/i915: Disable DC states for all commits
In reply to Greg Kroah-HartmanFrom: Ville Syrjälä <[email protected]>
commit a2b6e99d8a623544f3bdccd28ee35b9c1b00daa5 upstream.
Keeping DC states enabled is incompatible with the _noarm()/_arm() split we use for writing pipe/plane registers. When DC5 and PSR are enabled, all pipe/plane registers effectively become self-arming on account of DC5 exit arming the update, and PSR exit latching it.
What probably saves us most of the time is that (with PIPE_MISC[21]=0) all pipe register writes themselves trigger PSR exit, and then we don't re-enter PSR until the idle frame count has elapsed. So it may be that the PSR exit happens already before we've updated the state too much.
Also the PSR1 panel (at least on this KBL) seems to discard the first frame we trasmit, presumably still scanning out from its internal framebuffer at that point. So only the second frame we transmit is actually visible. But I suppose that could also be panel specific behaviour. I haven't checked out how other PSR panels behave, nor did I bother to check what the eDP spec has to say about this.
And since this really is all about DC states, let's switch from the MODESET domain to the DC_OFF domain. Functionally they are 100% identical. We should probably remove the MODESET domain...
And for good measure let's toss in an assert to the place where we do the _noarm() register writes to make sure DC states are in fact off.
v2: Just use intel_display_power_is_enabled() (Imre)
--- drivers/gpu/drm/i915/display/intel_display.c | 28 ++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-)
drivers/gpu/drm/i915/display/intel_display.c +25 -3
@@ -7124,6 +7124,8 @@ static void intel_update_crtc(struct intintel_fbc_update (state, crtc); +drm_WARN_ON (&i915->drm, !intel_display_power_is_enabled (i915,POWER_DOMAIN_DC_OFF )); +if (!modeset && (new_crtc_state->uapi.color_mgmt_changed || new_crtc_state->update_pipe))
@@ -7500,8 +7502,28 @@ static void intel_atomic_commit_tail(strdrm_atomic_helper_wait_for_dependencies (&state->base);drm_dp_mst_atomic_wait_for_dependencies (&state->base); -if (state->modeset) - wakeref =intel_display_power_get (dev_priv,POWER_DOMAIN_MODESET ); +/* +* During full modesets we write a lot of registers, wait +* for PLLs, etc. Doing that while DC states are enabled +* is not a good idea. +* +* During fastsets and other updates we also need to +* disable DC states due to the following scenario: +* 1. DC5 exit and PSR exit happen +* 2. Some or all _noarm() registers are written +* 3. Due to some long delay PSR is re-entered +* 4. DC5 entry -> DMC saves the already written new +* _noarm() registers and the old not yet written +* _arm() registers +* 5. DC5 exit -> DMC restores a mixture of old and +* new register values and arms the update +* 6. PSR exit -> hardware latches a mixture of old and +* new register values -> corrupted frame, or worse +* 7. New _arm() registers are finally written +* 8. Hardware finally latches a complete set of new +* register values, and subsequent frames will be OK again +*/ + wakeref =intel_display_power_get (dev_priv,POWER_DOMAIN_DC_OFF );intel_atomic_prepare_plane_clear_colors (state);
@@ -7640,8 +7662,8 @@ static void intel_atomic_commit_tail(str* the culprit. */ intel_uncore_arm_unclaimed_mmio_detection (&dev_priv->uncore); -intel_display_power_put (dev_priv,POWER_DOMAIN_MODESET , wakeref); } +intel_display_power_put (dev_priv,POWER_DOMAIN_DC_OFF , wakeref);intel_runtime_pm_put (&dev_priv->runtime_pm, state->wakeref);/*
Greg Kroah-Hartman
maintainerPATCH 168/181 drm/i915: Move CSC load back into .color_commit_arm() when PSR is enabled on skl/glk
In reply to Greg Kroah-HartmanFrom: Ville Syrjälä <[email protected]>
commit a8e03e00b62073b494886dbff32f8b5338066c8b upstream.
SKL/GLK CSC unit suffers from a nasty issue where a CSC coeff/offset register read or write between DC5 exit and PSR exit will undo the CSC arming performed by DMC, and then during PSR exit the hardware will latch zeroes into the active CSC registers. This causes any plane going through the CSC to output all black.
We can sidestep the issue by making sure the PSR exit has already actually happened before we touch the CSC coeff/offset registers. Easiest way to guarantee that is to just move the CSC programming back into the .color_commir_arm() as we force a PSR exit (and crucially wait for it to actually happen) prior to touching the arming registers.
When PSR (and thus also DC states) are disabled we don't have anything to worry about, so we can keep using the more optional _noarm() hook for writing the CSC registers.
--- drivers/gpu/drm/i915/display/intel_color.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/display/intel_color.c +21 -2
@@ -499,6 +499,22 @@ static void icl_color_commit_noarm(consticl_load_csc_matrix (crtc_state); } +static void skl_color_commit_noarm (const struct intel_crtc_state *crtc_state) +{ +/* +* Possibly related to display WA #1184, SKL CSC loses the latched +* CSC coeff/offset register values if the CSC registers are disarmed +* between DC5 exit and PSR exit. This will cause the plane(s) to +* output all black (until CSC_MODE is rearmed and properly latched). +* Once PSR exit (and proper register latching) has occurred the +* danger is over. Thus when PSR is enabled the CSC coeff/offset +* register programming will be peformed from skl_color_commit_arm() +* which is called after PSR exit. +*/ +if (!crtc_state->has_psr) +ilk_load_csc_matrix (crtc_state); +} +static void ilk_color_commit_noarm (const struct intel_crtc_state *crtc_state) {ilk_load_csc_matrix (crtc_state);
@@ -541,6 +557,9 @@ static void skl_color_commit_arm(const senum pipe pipe = crtc->pipe;u32 val =0 ; +if (crtc_state->has_psr) +ilk_load_csc_matrix (crtc_state); +/* * We don't (yet) allow userspace to control the pipe background color, * so force it to black, but apply pipe gamma and CSC appropriately
@@ -2171,7 +2190,7 @@ static const struct intel_color_funcs icstatic const struct intel_color_funcs glk_color_funcs = { .color_check = glk_color_check, - .color_commit_noarm = ilk_color_commit_noarm, + .color_commit_noarm = skl_color_commit_noarm, .color_commit_arm = skl_color_commit_arm, .load_luts = glk_load_luts, .read_luts = glk_read_luts,
@@ -2179,7 +2198,7 @@ static const struct intel_color_funcs glstatic const struct intel_color_funcs skl_color_funcs = { .color_check = ivb_color_check, - .color_commit_noarm = ilk_color_commit_noarm, + .color_commit_noarm = skl_color_commit_noarm, .color_commit_arm = skl_color_commit_arm, .load_luts = bdw_load_luts, .read_luts =NULL ,
Greg Kroah-Hartman
maintainerPATCH 169/181 KVM: arm64: PMU: Fix GET_ONE_REG for vPMC regs to return the current value
In reply to Greg Kroah-HartmanFrom: Reiji Watanabe <[email protected]>
commit 9228b26194d1cc00449f12f306f53ef2e234a55b upstream.
Have KVM_GET_ONE_REG for vPMU counter (vPMC) registers (PMCCNTR_EL0 and PMEVCNTR<n>_EL0) return the sum of the register value in the sysreg file and the current perf event counter value.
Values of vPMC registers are saved in sysreg files on certain occasions. These saved values don't represent the current values of the vPMC registers if the perf events for the vPMCs count events after the save. The current values of those registers are the sum of the sysreg file value and the current perf event counter value. But, when userspace reads those registers (using KVM_GET_ONE_REG), KVM returns the sysreg file value to userspace (not the sum value).
Fix this to return the sum value for KVM_GET_ONE_REG.
--- arch/arm64/kvm/sys_regs.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
arch/arm64/kvm/sys_regs.c +19 -2
@@ -767,6 +767,22 @@ static bool pmu_counter_idx_valid(structreturn true; } +static int get_pmu_evcntr (struct kvm_vcpu *vcpu,const struct sys_reg_desc *r, +u64 *val) +{ +u64 idx; + +if (r->CRn ==9 && r->CRm ==13 && r->Op2 ==0 ) +/* PMCCNTR_EL0 */ + idx =ARMV8_PMU_CYCLE_IDX ; +else +/* PMEVCNTRn_EL0 */ + idx = ((r->CRm &3 ) <<3 ) | (r->Op2 &7 ); + + *val =kvm_pmu_get_counter_value (vcpu, idx); +return 0 ; +} +static bool access_pmu_evcntr (struct kvm_vcpu *vcpu,struct sys_reg_params *p,const struct sys_reg_desc *r)
@@ -983,7 +999,7 @@ static bool access_pmuserenr(struct kvm_/* Macro to expand the PMEVCNTRn_EL0 register */ #define PMU_PMEVCNTR_EL0 (n) \ { PMU_SYS_REG(SYS_PMEVCNTRn_EL0(n)), \ - .reset = reset_pmevcntr, \ + .reset = reset_pmevcntr, .get_user = get_pmu_evcntr, \ .access = access_pmu_evcntr, .reg = (PMEVCNTR0_EL0 + n), }/* Macro to expand the PMEVTYPERn_EL0 register */
@@ -1632,7 +1648,8 @@ static const struct sys_reg_desc sys_reg { PMU_SYS_REG(SYS_PMCEID1_EL0), .access = access_pmceid, .reset = NULL }, { PMU_SYS_REG(SYS_PMCCNTR_EL0), - .access = access_pmu_evcntr, .reset = reset_unknown, .reg = PMCCNTR_EL0 }, + .access = access_pmu_evcntr, .reset = reset_unknown, + .reg = PMCCNTR_EL0, .get_user = get_pmu_evcntr}, { PMU_SYS_REG(SYS_PMXEVTYPER_EL0), .access = access_pmu_evtyper, .reset = NULL }, { PMU_SYS_REG(SYS_PMXEVCNTR_EL0),
Greg Kroah-Hartman
maintainerPATCH 170/181 KVM: arm64: Disable interrupts while walking userspace PTs
In reply to Greg Kroah-HartmanFrom: Marc Zyngier <[email protected]>
commit e86fc1a3a3e9b4850fe74d738e3cfcf4297d8bba upstream.
We walk the userspace PTs to discover what mapping size was used there. However, this can race against the userspace tables being freed, and we end-up in the weeds.
Thankfully, the mm code is being generous and will IPI us when doing so. So let's implement our part of the bargain and disable interrupts around the walk. This ensures that nothing terrible happens during that time.
We still need to handle the removal of the page tables before the walk. For that, allow get_user_mapping_size() to return an error, and make sure this error can be propagated all the way to the the exit handler.
--- arch/arm64/kvm/mmu.c | 45 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-)
arch/arm64/kvm/mmu.c +38 -7
@@ -646,14 +646,33 @@ static int get_user_mapping_size(struct CONFIG_PGTABLE_LEVELS), .mm_ops = &kvm_user_mm_ops, }; +unsigned long flags;kvm_pte_t pte =0 ;/* Keep GCC quiet... */ u32 level = ~0 ;int ret; +/* +* Disable IRQs so that we hazard against a concurrent +* teardown of the userspace page tables (which relies on +* IPI-ing threads). +*/ +local_irq_save (flags); ret =kvm_pgtable_get_leaf (&pgt, addr, &pte, &level); -VM_BUG_ON (ret); -VM_BUG_ON (level >=KVM_PGTABLE_MAX_LEVELS ); -VM_BUG_ON (!(pte &PTE_VALID )); +local_irq_restore (flags); + +if (ret) +return ret; + +/* +* Not seeing an error, but not updating level? Something went +* deeply wrong... +*/ +if (WARN_ON (level >=KVM_PGTABLE_MAX_LEVELS )) +return -EFAULT ; + +/* Oops, the userspace PTs are gone... Replay the fault */ +if (!kvm_pte_valid (pte)) +return -EAGAIN ;return BIT (ARM64_HW_PGTABLE_LEVEL_SHIFT (level)); }
@@ -1006,7 +1025,7 @@ static bool fault_supports_stage2_huge_m* * Returns the size of the mapping. */ -static unsigned long +static long transparent_hugepage_adjust (struct kvm *kvm,struct kvm_memory_slot *memslot,unsigned long hva,kvm_pfn_t *pfnp,phys_addr_t *ipap)
@@ -1018,8 +1037,15 @@ transparent_hugepage_adjust(struct kvm ** sure that the HVA and IPA are sufficiently aligned and that the * block map is contained within the memslot. */ -if (fault_supports_stage2_huge_mapping (memslot, hva,PMD_SIZE ) && -get_user_mapping_size (kvm, hva) >=PMD_SIZE ) { +if (fault_supports_stage2_huge_mapping (memslot, hva,PMD_SIZE )) { +int sz =get_user_mapping_size (kvm, hva); + +if (sz <0 ) +return sz; + +if (sz <PMD_SIZE ) +return PAGE_SIZE ; +/* * The address we faulted on is backed by a transparent huge * page. However, because we map the compound huge page and
@@ -1138,7 +1164,7 @@ static int user_mem_abort(struct kvm_vcpbool logging_active =memslot_is_logging (memslot);bool use_read_lock = false;unsigned long fault_level =kvm_vcpu_trap_get_fault_level (vcpu); -unsigned long vma_pagesize, fault_granule; +long vma_pagesize, fault_granule;enum kvm_pgtable_prot prot =KVM_PGTABLE_PROT_R ;struct kvm_pgtable *pgt;
@@ -1295,6 +1321,11 @@ static int user_mem_abort(struct kvm_vcp vma_pagesize =transparent_hugepage_adjust (kvm, memslot, hva, &pfn, &fault_ipa); + +if (vma_pagesize <0 ) { + ret = vma_pagesize; + goto out_unlock; + } }if (fault_status !=FSC_PERM && !device &&kvm_has_mte (kvm)) {
Greg Kroah-Hartman
maintainerPATCH 171/181 net: dsa: mv88e6xxx: read FID when handling ATU violations
In reply to Greg Kroah-HartmanFrom: Hans J. Schultz <[email protected]>
commit 4bf24ad09bc0b05e97fb48b962b2c9246fc76727 upstream.
When an ATU violation occurs, the switch uses the ATU FID register to report the FID of the MAC address that incurred the violation. It would be good for the driver to know the FID value for purposes such as logging and CPU-based authentication.
Up until now, the driver has been calling the mv88e6xxx_g1_atu_op() function to read ATU violations, but that doesn't do exactly what we want, namely it calls mv88e6xxx_g1_atu_fid_write() with FID 0. (side note, the documentation for the ATU Get/Clear Violation command says that writes to the ATU FID register have no effect before the operation starts, it's only that we disregard the value that this register provides once the operation completes)
So mv88e6xxx_g1_atu_fid_write() is not what we want, but rather mv88e6xxx_g1_atu_fid_read(). However, the latter doesn't exist, we need to write it.
The remainder of mv88e6xxx_g1_atu_op() except for mv88e6xxx_g1_atu_fid_write() is still needed, namely to send a GET_CLR_VIOLATION command to the ATU. In principle we could have still kept calling mv88e6xxx_g1_atu_op(), but the MDIO writes to the ATU FID register are pointless, but in the interest of doing less CPU work per interrupt, write a new function called mv88e6xxx_g1_read_atu_violation() and call it.
The FID will be the port default FID as set by mv88e6xxx_port_set_fid() if the VID from the packet cannot be found in the VTU. Otherwise it is the FID derived from the VTU entry associated with that VID.
--- drivers/net/dsa/mv88e6xxx/global1_atu.c | 72 +++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 11 deletions(-)
drivers/net/dsa/mv88e6xxx/global1_atu.c +61 -11
@@ -114,6 +114,19 @@ static int mv88e6xxx_g1_atu_op_wait(strureturn mv88e6xxx_g1_wait_bit (chip,MV88E6XXX_G1_ATU_OP , bit,0 ); } +static int mv88e6xxx_g1_read_atu_violation (struct mv88e6xxx_chip *chip) +{ +int err; + + err =mv88e6xxx_g1_write (chip,MV88E6XXX_G1_ATU_OP , +MV88E6XXX_G1_ATU_OP_BUSY | +MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION ); +if (err) +return err; + +return mv88e6xxx_g1_atu_op_wait (chip); +} +static int mv88e6xxx_g1_atu_op (struct mv88e6xxx_chip *chip,u16 fid,u16 op) {u16 val;
@@ -159,6 +172,41 @@ int mv88e6xxx_g1_atu_get_next(struct mv8return mv88e6xxx_g1_atu_op (chip, fid,MV88E6XXX_G1_ATU_OP_GET_NEXT_DB ); } +static int mv88e6xxx_g1_atu_fid_read (struct mv88e6xxx_chip *chip,u16 *fid) +{ +u16 val =0 , upper =0 , op =0 ; +int err = -EOPNOTSUPP ; + +if (mv88e6xxx_num_databases (chip) >256 ) { + err =mv88e6xxx_g1_read (chip,MV88E6352_G1_ATU_FID , &val); + val &=0xfff ; +if (err) +return err; + }else { + err =mv88e6xxx_g1_read (chip,MV88E6XXX_G1_ATU_OP , &op); +if (err) +return err; +if (mv88e6xxx_num_databases (chip) >64 ) { +/* ATU DBNum[7:4] are located in ATU Control 15:12 */ + err =mv88e6xxx_g1_read (chip,MV88E6XXX_G1_ATU_CTL , + &upper); +if (err) +return err; + + upper = (upper >>8 ) &0x00f0 ; + }else if (mv88e6xxx_num_databases (chip) >16 ) { +/* ATU DBNum[5:4] are located in ATU Operation 9:8 */ + upper = (op >>4 ) &0x30 ; + } + +/* ATU DBNum[3:0] are located in ATU Operation 3:0 */ + val = (op &0xf ) | upper; + } + *fid = val; + +return err; +} +/* Offset 0x0C: ATU Data Register */ static int mv88e6xxx_g1_atu_data_read(struct mv88e6xxx_chip *chip,
@@ -353,14 +401,12 @@ static irqreturn_t mv88e6xxx_g1_atu_prob {struct mv88e6xxx_chip *chip = dev_id;struct mv88e6xxx_atu_entry entry; -int spid; -int err; -u16 val; +int err, spid; +u16 val, fid;mv88e6xxx_reg_lock (chip); - err =mv88e6xxx_g1_atu_op (chip,0 , -MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION ); + err =mv88e6xxx_g1_read_atu_violation (chip);if (err) goto out;
@@ -368,6 +414,10 @@ static irqreturn_t mv88e6xxx_g1_atu_probif (err) goto out; + err =mv88e6xxx_g1_atu_fid_read (chip, &fid); +if (err) + goto out; + err =mv88e6xxx_g1_atu_data_read (chip, &entry);if (err) goto out;
@@ -386,22 +436,22 @@ static irqreturn_t mv88e6xxx_g1_atu_probif (val &MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION ) {dev_err_ratelimited (chip->dev, -"ATU member violation for %pM portvec %x spid %d\n" , - entry.mac, entry.portvec, spid); +"ATU member violation for %pM fid %u portvec %x spid %d\n" , + entry.mac, fid, entry.portvec, spid); chip->ports[spid].atu_member_violation++; }if (val &MV88E6XXX_G1_ATU_OP_MISS_VIOLATION ) {dev_err_ratelimited (chip->dev, -"ATU miss violation for %pM portvec %x spid %d\n" , - entry.mac, entry.portvec, spid); +"ATU miss violation for %pM fid %u portvec %x spid %d\n" , + entry.mac, fid, entry.portvec, spid); chip->ports[spid].atu_miss_violation++; }if (val &MV88E6XXX_G1_ATU_OP_FULL_VIOLATION ) {dev_err_ratelimited (chip->dev, -"ATU full violation for %pM portvec %x spid %d\n" , - entry.mac, entry.portvec, spid); +"ATU full violation for %pM fid %u portvec %x spid %d\n" , + entry.mac, fid, entry.portvec, spid); chip->ports[spid].atu_full_violation++; }mv88e6xxx_reg_unlock (chip);
Greg Kroah-Hartman
maintainerPATCH 172/181 net: dsa: mv88e6xxx: replace ATU violation prints with trace points
In reply to Greg Kroah-HartmanFrom: Vladimir Oltean <[email protected]>
commit 8646384d80f3d3b4a66b3284dbbd8232d1b8799e upstream.
In applications where the switch ports must perform 802.1X based authentication and are therefore locked, ATU violation interrupts are quite to be expected as part of normal operation. The problem is that they currently spam the kernel log, even if rate limited.
Create a series of trace points, all derived from the same event class, which log these violations to the kernel's trace buffer, which is both much faster and much easier to ignore than printing to a serial console.
New usage model:
$ trace-cmd list | grep mv88e6xxx mv88e6xxx mv88e6xxx:mv88e6xxx_atu_full_violation mv88e6xxx:mv88e6xxx_atu_miss_violation mv88e6xxx:mv88e6xxx_atu_member_violation $ trace-cmd record -e mv88e6xxx sleep 10
--- drivers/net/dsa/mv88e6xxx/Makefile | 4 + drivers/net/dsa/mv88e6xxx/global1_atu.c | 19 ++++----- drivers/net/dsa/mv88e6xxx/trace.c | 6 ++ drivers/net/dsa/mv88e6xxx/trace.h | 66 ++++++++++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 drivers/net/dsa/mv88e6xxx/trace.c create mode 100644 drivers/net/dsa/mv88e6xxx/trace.h
drivers/net/dsa/mv88e6xxx/Makefile +4 -0
@@ -15,3 +15,7 @@ mv88e6xxx-objs += port_hidden.o mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += ptp.o mv88e6xxx-objs += serdes.o mv88e6xxx-objs += smi.o +mv88e6xxx-objs += trace.o + +# for tracing framework to find trace.h +CFLAGS_trace.o := -I$(src)
drivers/net/dsa/mv88e6xxx/global1_atu.c +10 -9
@@ -12,6 +12,7 @@#include "chip.h" #include "global1.h" +#include "trace.h" /* Offset 0x01: ATU FID Register */
@@ -435,23 +436,23 @@ static irqreturn_t mv88e6xxx_g1_atu_prob }if (val &MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION ) { -dev_err_ratelimited (chip->dev, -"ATU member violation for %pM fid %u portvec %x spid %d\n" , - entry.mac, fid, entry.portvec, spid); +trace_mv88e6xxx_atu_member_violation (chip->dev, spid, + entry.portvec, entry.mac, + fid); chip->ports[spid].atu_member_violation++; }if (val &MV88E6XXX_G1_ATU_OP_MISS_VIOLATION ) { -dev_err_ratelimited (chip->dev, -"ATU miss violation for %pM fid %u portvec %x spid %d\n" , - entry.mac, fid, entry.portvec, spid); +trace_mv88e6xxx_atu_miss_violation (chip->dev, spid, + entry.portvec, entry.mac, + fid); chip->ports[spid].atu_miss_violation++; }if (val &MV88E6XXX_G1_ATU_OP_FULL_VIOLATION ) { -dev_err_ratelimited (chip->dev, -"ATU full violation for %pM fid %u portvec %x spid %d\n" , - entry.mac, fid, entry.portvec, spid); +trace_mv88e6xxx_atu_full_violation (chip->dev, spid, + entry.portvec, entry.mac, + fid); chip->ports[spid].atu_full_violation++; }mv88e6xxx_reg_unlock (chip);
drivers/net/dsa/mv88e6xxx/trace.c new file +6 -0
@@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* Copyright 2022 NXP +*/ + +#define CREATE_TRACE_POINTS +#include "trace.h"
drivers/net/dsa/mv88e6xxx/trace.h new file +66 -0
66 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 173/181 net: dsa: mv88e6xxx: replace VTU violation prints with trace points
In reply to Greg Kroah-HartmanFrom: Vladimir Oltean <[email protected]>
commit 9e3d9ae52b5657399a7b61258cc7482434a911bb upstream.
It is possible to trigger these VTU violation messages very easily, it's only necessary to send packets with an unknown VLAN ID to a port that belongs to a VLAN-aware bridge.
Do a similar thing as for ATU violation messages, and hide them in the kernel's trace buffer.
New usage model:
$ trace-cmd list | grep mv88e6xxx mv88e6xxx mv88e6xxx:mv88e6xxx_vtu_miss_violation mv88e6xxx:mv88e6xxx_vtu_member_violation $ trace-cmd report
--- drivers/net/dsa/mv88e6xxx/global1_vtu.c | 7 +++---- drivers/net/dsa/mv88e6xxx/trace.h | 30 ++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-)
drivers/net/dsa/mv88e6xxx/global1_vtu.c +3 -4
@@ -13,6 +13,7 @@#include "chip.h" #include "global1.h" +#include "trace.h" /* Offset 0x02: VTU FID Register */
@@ -628,14 +629,12 @@ static irqreturn_t mv88e6xxx_g1_vtu_prob spid = val &MV88E6XXX_G1_VTU_OP_SPID_MASK ;if (val &MV88E6XXX_G1_VTU_OP_MEMBER_VIOLATION ) { -dev_err_ratelimited (chip->dev,"VTU member violation for vid %d, source port %d\n" , - vid, spid); +trace_mv88e6xxx_vtu_member_violation (chip->dev, spid, vid); chip->ports[spid].vtu_member_violation++; }if (val &MV88E6XXX_G1_VTU_OP_MISS_VIOLATION ) { -dev_dbg_ratelimited (chip->dev,"VTU miss violation for vid %d, source port %d\n" , - vid, spid); +trace_mv88e6xxx_vtu_miss_violation (chip->dev, spid, vid); chip->ports[spid].vtu_miss_violation++; }
drivers/net/dsa/mv88e6xxx/trace.h +30 -0
@@ -55,6 +55,36 @@ DEFINE_EVENT(mv88e6xxx_atu_violation, mv const unsigned char *addr, u16 fid), TP_ARGS(dev, spid, portvec, addr, fid)); +DECLARE_EVENT_CLASS (mv88e6xxx_vtu_violation, + + TP_PROTO(const struct device *dev, int spid, u16 vid), + +TP_ARGS (dev, spid, vid), + +TP_STRUCT__entry ( + __string(name, dev_name(dev)) + __field(int, spid) +__field (u16, vid) + ), + +TP_fast_assign ( + __assign_str(name, dev_name(dev)); + __entry->spid = spid; + __entry->vid = vid; + ), + +TP_printk ("dev %s spid %d vid %u" , +__get_str (name), __entry->spid, __entry->vid) +); + +DEFINE_EVENT (mv88e6xxx_vtu_violation, mv88e6xxx_vtu_member_violation, + TP_PROTO(const struct device *dev, int spid, u16 vid), +TP_ARGS (dev, spid, vid)); + +DEFINE_EVENT (mv88e6xxx_vtu_violation, mv88e6xxx_vtu_miss_violation, + TP_PROTO(const struct device *dev, int spid, u16 vid), +TP_ARGS (dev, spid, vid)); +#endif /* _MV88E6XXX_TRACE_H */ /* We don't want to use include/trace/events */
Greg Kroah-Hartman
maintainerPATCH 174/181 selftests/bpf: Test btf dump for struct with padding only fields
In reply to Greg Kroah-HartmanFrom: Eduard Zingerman <[email protected]>
[ Upstream commit d503f1176b14f722a40ea5110312614982f9a80b ]
Structures with zero regular fields but some padding constitute a special case in btf_dump.c:btf_dump_emit_struct_def with regards to newline before closing '}'.
Stable-dep-of: ea2ce1ba99aa ("libbpf: Fix BTF-to-C converter's padding logic")
--- .../selftests/bpf/progs/btf_dump_test_case_padding.c | 9 +++++++++ 1 file changed, 9 insertions(+)
tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c +9 -0
@@ -102,12 +102,21 @@ struct zone {struct zone_padding __pad__; }; +/* ----- START-EXPECTED-OUTPUT ----- */ +struct padding_wo_named_members { + long: 64; + long: 64; +}; + +/* ------ END-EXPECTED-OUTPUT ------ */ +int f (struct {struct padded_implicitly _1;struct padded_explicitly _2;struct padded_a_lot _3;struct padded_cache_line _4;struct zone _5; +struct padding_wo_named_members _6; } *_) {return 0 ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 175/181 libbpf: Fix BTF-to-C converters padding logic
In reply to Greg Kroah-HartmanFrom: Andrii Nakryiko <[email protected]>
[ Upstream commit ea2ce1ba99aa6a60c8d8a706e3abadf3de372163 ]
Turns out that btf_dump API doesn't handle a bunch of tricky corner cases, as reported by Per, and further discovered using his testing Python script ([0]).
This patch revamps btf_dump's padding logic significantly, making it more correct and also avoiding unnecessary explicit padding, where compiler would pad naturally. This overall topic turned out to be very tricky and subtle, there are lots of subtle corner cases. The comments in the code tries to give some clues, but comments themselves are supposed to be paired with good understanding of C alignment and padding rules. Plus some experimentation to figure out subtle things like whether long :0; means that struct is now forced to be long-aligned (no, it's not, turns out).
Anyways, Per's script, while not completely correct in some known situations, doesn't show any obvious cases where this logic breaks, so this is a nice improvement over the previous state of this logic.
Some selftests had to be adjusted to accommodate better use of natural alignment rules, eliminating some unnecessary padding, or changing it to type: 0; alignment markers.
Note also that for when we are in between bitfields, we emit explicit bit size, while otherwise we use : 0, this feels much more natural in practice.
Next patch will add few more test cases, found through randomized Per's script.
[0] https://lore.kernel.org/bpf/[email protected]/
--- tools/lib/bpf/btf_dump.c | 169 +++++++++++++----- .../bpf/progs/btf_dump_test_case_bitfields.c | 2 +- .../bpf/progs/btf_dump_test_case_padding.c | 58 ++++-- 3 files changed, 164 insertions(+), 65 deletions(-)
tools/lib/bpf/btf_dump.c +123 -46
@@ -829,6 +829,25 @@ static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id) } } +static int btf_natural_align_of (const struct btf *btf,__u32 id) +{ +const struct btf_type *t =btf__type_by_id (btf, id); +int i, align, vlen; +const struct btf_member *m; + +if (!btf_is_composite (t)) +return btf__align_of (btf, id); + + align =1 ; + m =btf_members (t); + vlen =btf_vlen (t); +for (i =0 ; i < vlen; i++, m++) { + align =max (align,btf__align_of (btf, m->type)); + } + +return align; +} +static bool btf_is_struct_packed (const struct btf *btf,__u32 id,const struct btf_type *t) {
@@ -836,16 +855,16 @@ static bool btf_is_struct_packed(const struct btf *btf, __u32 id,int align, i, bit_sz;__u16 vlen; - align =btf__align_of (btf, id); -/* size of a non-packed struct has to be a multiple of its alignment*/ -if (align && t->size % align) + align =btf_natural_align_of (btf, id); +/* size of a non-packed struct has to be a multiple of its alignment */ +if (align && (t->size % align) !=0 )return true; m =btf_members (t); vlen =btf_vlen (t);/* all non-bitfield fields have to be naturally aligned */ for (i =0 ; i < vlen; i++, m++) { - align =btf__align_of (btf, m->type); + align =btf_natural_align_of (btf, m->type); bit_sz =btf_member_bitfield_size (t, i);if (align && bit_sz ==0 && m->offset % (8 * align) !=0 )return true;
@@ -858,44 +877,97 @@ static bool btf_is_struct_packed(const struct btf *btf, __u32 id,return false; } -static int chip_away_bits (int total,int at_most) -{ -return total % at_most ? : at_most; -} -static void btf_dump_emit_bit_padding (const struct btf_dump *d, -int cur_off,int m_off,int m_bit_sz, -int align,int lvl) +int cur_off,int next_off,int next_align, +bool in_bitfield,int lvl) { -int off_diff = m_off - cur_off; -int ptr_bits = d->ptr_sz *8 ; +const struct { +const char *name; +int bits; + } pads[] = { + {"long" , d->ptr_sz *8 }, {"int" ,32 }, {"short" ,16 }, {"char" ,8 } + }; +int new_off, pad_bits, bits, i; +const char *pad_type; + +if (cur_off >= next_off) +return ;/* no gap */ + +/* For filling out padding we want to take advantage of +* natural alignment rules to minimize unnecessary explicit +* padding. First, we find the largest type (among long, int, +* short, or char) that can be used to force naturally aligned +* boundary. Once determined, we'll use such type to fill in +* the remaining padding gap. In some cases we can rely on +* compiler filling some gaps, but sometimes we need to force +* alignment to close natural alignment with markers like +* `long: 0` (this is always the case for bitfields). Note +* that even if struct itself has, let's say 4-byte alignment +* (i.e., it only uses up to int-aligned types), using `long: +* X;` explicit padding doesn't actually change struct's +* overall alignment requirements, but compiler does take into +* account that type's (long, in this example) natural +* alignment requirements when adding implicit padding. We use +* this fact heavily and don't worry about ruining correct +* struct alignment requirement. +*/ +for (i =0 ; i <ARRAY_SIZE (pads); i++) { + pad_bits = pads[i].bits; + pad_type = pads[i].name; -if (off_diff <=0 ) -/* no gap */ -return ; -if (m_bit_sz ==0 && off_diff < align *8 ) -/* natural padding will take care of a gap */ -return ; + new_off =roundup (cur_off, pad_bits); +if (new_off <= next_off) +break ; + } -while (off_diff >0 ) { -const char *pad_type; -int pad_bits; - -if (ptr_bits >32 && off_diff >32 ) { - pad_type ="long" ; - pad_bits =chip_away_bits (off_diff, ptr_bits); - }else if (off_diff >16 ) { - pad_type ="int" ; - pad_bits =chip_away_bits (off_diff,32 ); - }else if (off_diff >8 ) { - pad_type ="short" ; - pad_bits =chip_away_bits (off_diff,16 ); - }else { - pad_type ="char" ; - pad_bits =chip_away_bits (off_diff,8 ); +if (new_off > cur_off && new_off <= next_off) { +/* We need explicit `<type>: 0` aligning mark if next +* field is right on alignment offset and its +* alignment requirement is less strict than <type>'s +* alignment (so compiler won't naturally align to the +* offset we expect), or if subsequent `<type>: X`, +* will actually completely fit in the remaining hole, +* making compiler basically ignore `<type>: X` +* completely. +*/ +if (in_bitfield || + (new_off == next_off &&roundup (cur_off, next_align *8 ) != new_off) || + (new_off != next_off && next_off - new_off <= new_off - cur_off)) +/* but for bitfields we'll emit explicit bit count */ +btf_dump_printf (d,"\n%s%s: %d;" ,pfx (lvl), pad_type, + in_bitfield ? new_off - cur_off :0 ); + cur_off = new_off; + } + +/* Now we know we start at naturally aligned offset for a chosen +* padding type (long, int, short, or char), and so the rest is just +* a straightforward filling of remaining padding gap with full +* `<type>: sizeof(<type>);` markers, except for the last one, which +* might need smaller than sizeof(<type>) padding. +*/ +while (cur_off != next_off) { + bits =min (next_off - cur_off, pad_bits); +if (bits == pad_bits) { +btf_dump_printf (d,"\n%s%s: %d;" ,pfx (lvl), pad_type, pad_bits); + cur_off += bits; +continue ; + } +/* For the remainder padding that doesn't cover entire +* pad_type bit length, we pick the smallest necessary type. +* This is pure aesthetics, we could have just used `long`, +* but having smallest necessary one communicates better the +* scale of the padding gap. +*/ +for (i =ARRAY_SIZE (pads) -1 ; i >=0 ; i--) { + pad_type = pads[i].name; + pad_bits = pads[i].bits; +if (pad_bits < bits) +continue ; + +btf_dump_printf (d,"\n%s%s: %d;" ,pfx (lvl), pad_type, bits); + cur_off += bits; +break ; } -btf_dump_printf (d,"\n%s%s: %d;" ,pfx (lvl), pad_type, pad_bits); - off_diff -= pad_bits; } }
@@ -915,9 +987,11 @@ static void btf_dump_emit_struct_def(struct btf_dump *d, {const struct btf_member *m =btf_members (t);bool is_struct =btf_is_struct (t); -int align, i, packed, off =0 ; +bool packed, prev_bitfield = false; +int align, i, off =0 ;__u16 vlen =btf_vlen (t); + align =btf__align_of (d->btf, id); packed = is_struct ?btf_is_struct_packed (d->btf, id, t) :0 ; btf_dump_printf(d, "%s%s%s {",
@@ -927,33 +1001,36 @@ static void btf_dump_emit_struct_def(struct btf_dump *d,for (i =0 ; i < vlen; i++, m++) {const char *fname; -int m_off, m_sz; +int m_off, m_sz, m_align; +bool in_bitfield; fname =btf_name_of (d, m->name_off); m_sz =btf_member_bitfield_size (t, i); m_off =btf_member_bit_offset (t, i); - align = packed ?1 :btf__align_of (d->btf, m->type); + m_align = packed ?1 :btf__align_of (d->btf, m->type); + + in_bitfield = prev_bitfield && m_sz !=0 ; -btf_dump_emit_bit_padding (d, off, m_off, m_sz, align, lvl +1 ); +btf_dump_emit_bit_padding (d, off, m_off, m_align, in_bitfield, lvl +1 );btf_dump_printf (d,"\n%s" ,pfx (lvl +1 ));btf_dump_emit_type_decl (d, m->type, fname, lvl +1 );if (m_sz) {btf_dump_printf (d,": %d" , m_sz); off = m_off + m_sz; + prev_bitfield = true; }else { m_sz =max ((__s64 )0 ,btf__resolve_size (d->btf, m->type)); off = m_off + m_sz *8 ; + prev_bitfield = false; } +btf_dump_printf (d,";" ); }/* pad at the end, if necessary */ -if (is_struct) { - align = packed ?1 :btf__align_of (d->btf, id); -btf_dump_emit_bit_padding (d, off, t->size *8 ,0 , align, - lvl +1 ); - } +if (is_struct) +btf_dump_emit_bit_padding (d, off, t->size *8 , align, false, lvl +1 );if (vlen)btf_dump_printf (d,"\n" );
tools/testing/selftests/bpf/progs/btf_dump_test_case_bitfields.c +1 -1
@@ -53,7 +53,7 @@ struct bitfields_only_mixed_types {*/ /* ------ END-EXPECTED-OUTPUT ------ */ struct bitfield_mixed_with_others { - long: 4; /* char is enough as a backing field */ + char: 4; /* char is enough as a backing field */int a:4 ;/* 8-bit implicit padding */ short b;/* combined with previous bitfield */
tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c +40 -18
107 lines not on this page · raw message
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 176/181 selftests/bpf: Add few corner cases to test padding handling of btf_dump
In reply to Greg Kroah-HartmanFrom: Andrii Nakryiko <[email protected]>
[ Upstream commit b148c8b9b926e257a59c8eb2cd6fa3adfd443254 ]
Add few hand-crafted cases and few randomized cases found using script from [0] that tests btf_dump's padding logic.
[0] https://lore.kernel.org/bpf/[email protected]/
Stable-dep-of: 4fb877aaa179 ("libbpf: Fix btf_dump's packed struct determination")
--- .../bpf/progs/btf_dump_test_case_packing.c | 61 +++++++++- .../bpf/progs/btf_dump_test_case_padding.c | 104 ++++++++++++++++++ 2 files changed, 164 insertions(+), 1 deletion(-)
tools/testing/selftests/bpf/progs/btf_dump_test_case_packing.c +60 -1
@@ -58,7 +58,64 @@ union jump_code_union { } __attribute__((packed)); }; -/*------ END-EXPECTED-OUTPUT ------ */ +/* ----- START-EXPECTED-OUTPUT ----- */ +/* +*struct nested_packed_but_aligned_struct { +* int x1; +* int x2; +*}; +* +*struct outer_implicitly_packed_struct { +* char y1; +* struct nested_packed_but_aligned_struct y2; +*} __attribute__((packed)); +* +*/ +/* ------ END-EXPECTED-OUTPUT ------ */ + +struct nested_packed_but_aligned_struct { +int x1; +int x2; +} __attribute__((packed)); + +struct outer_implicitly_packed_struct { +char y1; +struct nested_packed_but_aligned_struct y2; +}; +/* ----- START-EXPECTED-OUTPUT ----- */ +/* +*struct usb_ss_ep_comp_descriptor { +* char: 8; +* char bDescriptorType; +* char bMaxBurst; +* short wBytesPerInterval; +*}; +* +*struct usb_host_endpoint { +* long: 64; +* char: 8; +* struct usb_ss_ep_comp_descriptor ss_ep_comp; +* long: 0; +*} __attribute__((packed)); +* +*/ +/* ------ END-EXPECTED-OUTPUT ------ */ + +struct usb_ss_ep_comp_descriptor { + char: 8; +char bDescriptorType; +char bMaxBurst; + int: 0; +short wBytesPerInterval; +} __attribute__((packed)); + +struct usb_host_endpoint { + long: 64; + char: 8; +struct usb_ss_ep_comp_descriptor ss_ep_comp; + long: 0; +}; + int f(struct { struct packed_trailing_space _1;
@@ -69,6 +126,8 @@ int f(struct {union union_is_never_packed _6;union union_does_not_need_packing _7;union jump_code_union _8; +struct outer_implicitly_packed_struct _9; +struct usb_host_endpoint _10; } *_) {return 0 ;
tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c +104 -0
116 lines not on this page · raw message
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 177/181 libbpf: Fix btf_dumps packed struct determination
In reply to Greg Kroah-HartmanFrom: Andrii Nakryiko <[email protected]>
[ Upstream commit 4fb877aaa179dcdb1676d55216482febaada457e ]
Fix bug in btf_dump's logic of determining if a given struct type is packed or not. The notion of "natural alignment" is not needed and is even harmful in this case, so drop it altogether. The biggest difference in btf_is_struct_packed() compared to its original implementation is that we don't really use btf__align_of() to determine overall alignment of a struct type (because it could be 1 for both packed and non-packed struct, depending on specifci field definitions), and just use field's actual alignment to calculate whether any field is requiring packing or struct's size overall necessitates packing.
Add two simple test cases that demonstrate the difference this change would make.
--- tools/lib/bpf/btf_dump.c | 33 ++++--------------- .../bpf/progs/btf_dump_test_case_packing.c | 19 +++++++++++ 2 files changed, 25 insertions(+), 27 deletions(-)
tools/lib/bpf/btf_dump.c +6 -27
@@ -829,47 +829,26 @@ static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id) } } -static int btf_natural_align_of (const struct btf *btf,__u32 id) -{ -const struct btf_type *t =btf__type_by_id (btf, id); -int i, align, vlen; -const struct btf_member *m; - -if (!btf_is_composite (t)) -return btf__align_of (btf, id); - - align =1 ; - m =btf_members (t); - vlen =btf_vlen (t); -for (i =0 ; i < vlen; i++, m++) { - align =max (align,btf__align_of (btf, m->type)); - } - -return align; -} -static bool btf_is_struct_packed (const struct btf *btf,__u32 id,const struct btf_type *t) {const struct btf_member *m; -int align, i, bit_sz; +int max_align =1 , align, i, bit_sz;__u16 vlen; - align =btf_natural_align_of (btf, id); -/* size of a non-packed struct has to be a multiple of its alignment */ -if (align && (t->size % align) !=0 ) -return true; - m =btf_members (t); vlen =btf_vlen (t);/* all non-bitfield fields have to be naturally aligned */ for (i =0 ; i < vlen; i++, m++) { - align =btf_natural_align_of (btf, m->type); + align =btf__align_of (btf, m->type); bit_sz =btf_member_bitfield_size (t, i);if (align && bit_sz ==0 && m->offset % (8 * align) !=0 )return true; + max_align =max (align, max_align); } - +/* size of a non-packed struct has to be a multiple of its alignment */ +if (t->size % max_align !=0 ) +return true;/* * if original struct was marked as packed, but its layout is * naturally aligned, we'll detect that it's not packed
tools/testing/selftests/bpf/progs/btf_dump_test_case_packing.c +19 -0
@@ -116,6 +116,23 @@ struct usb_host_endpoint { long: 0; }; +/* ----- START-EXPECTED-OUTPUT ----- */ +struct nested_packed_struct { +int a; +char b; +} __attribute__((packed)); + +struct outer_nonpacked_struct { +short a; +struct nested_packed_struct b; +}; + +struct outer_packed_struct { +short a; +struct nested_packed_struct b; +} __attribute__((packed)); + +/* ------ END-EXPECTED-OUTPUT ------ */ int f(struct { struct packed_trailing_space _1;
@@ -128,6 +145,8 @@ int f(struct {union jump_code_union _8;struct outer_implicitly_packed_struct _9;struct usb_host_endpoint _10; +struct outer_nonpacked_struct _11; +struct outer_packed_struct _12; } *_) {return 0 ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 178/181 usb: ucsi: Fix ucsi->connector race
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
commit 0482c34ec6f8557e06cd0f8e2d0e20e8ede6a22c upstream.
ucsi_init() which runs from a workqueue sets ucsi->connector and on an error will clear it again.
ucsi->connector gets dereferenced by ucsi_resume(), this checks for ucsi->connector being NULL in case ucsi_init() has not finished yet; or in case ucsi_init() has failed.
ucsi_init() setting ucsi->connector and then clearing it again on an error creates a race where the check in ucsi_resume() may pass, only to have ucsi->connector free-ed underneath it when ucsi_init() hits an error.
Fix this race by making ucsi_init() store the connector array in a local variable and only assign it to ucsi->connector on success.
--- drivers/usb/typec/ucsi/ucsi.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-)
drivers/usb/typec/ucsi/ucsi.c +9 -13
@@ -1039,9 +1039,8 @@ static struct fwnode_handle *ucsi_find_freturn NULL ; } -static int ucsi_register_port (struct ucsi *ucsi,int index) +static int ucsi_register_port (struct ucsi *ucsi,struct ucsi_connector *con) { -struct ucsi_connector *con = &ucsi->connector[index];struct typec_capability *cap = &con->typec_cap;enum typec_accessory *accessory = cap->accessory;enum usb_role u_role =USB_ROLE_NONE ;
@@ -1062,7 +1061,6 @@ static int ucsi_register_port(struct ucsinit_completion (&con->complete);mutex_init (&con->lock);INIT_LIST_HEAD (&con->partner_tasks); - con->num = index +1 ; con->ucsi = ucsi; cap->fwnode =ucsi_find_fwnode (con);
@@ -1204,7 +1202,7 @@ out_unlock:*/ static int ucsi_init (struct ucsi *ucsi) { -struct ucsi_connector *con; +struct ucsi_connector *con, *connector;u64 command, ntfy;int ret;int i;
@@ -1235,16 +1233,16 @@ static int ucsi_init(struct ucsi *ucsi) }/* Allocate the connectors. Released in ucsi_unregister() */ - ucsi->connector =kcalloc (ucsi->cap.num_connectors +1 , -sizeof (*ucsi->connector),GFP_KERNEL ); -if (!ucsi->connector) { + connector =kcalloc (ucsi->cap.num_connectors +1 ,sizeof (*connector),GFP_KERNEL ); +if (!connector) { ret = -ENOMEM ; goto err_reset; }/* Register all connectors */ for (i =0 ; i < ucsi->cap.num_connectors; i++) { - ret =ucsi_register_port (ucsi, i); + connector[i].num = i +1 ; + ret =ucsi_register_port (ucsi, &connector[i]);if (ret) goto err_unregister; }
@@ -1256,11 +1254,12 @@ static int ucsi_init(struct ucsi *ucsi)if (ret <0 ) goto err_unregister; + ucsi->connector = connector; ucsi->ntfy = ntfy;return 0 ; err_unregister: -for (con = ucsi->connector; con->port; con++) { +for (con = connector; con->port; con++) {ucsi_unregister_partner (con);ucsi_unregister_altmodes (con,UCSI_RECIPIENT_CON );ucsi_unregister_port_psy (con);
@@ -1269,10 +1268,7 @@ err_unregister:typec_unregister_port (con->port); con->port =NULL ; } - -kfree (ucsi->connector); - ucsi->connector =NULL ; - +kfree (connector); err_reset:memset (&ucsi->cap,0 ,sizeof (ucsi->cap));ucsi_reset_ppm (ucsi);
Greg Kroah-Hartman
maintainerPATCH 179/181 drm/amdkfd: Get prange->offset after svm_range_vram_node_new
In reply to Greg Kroah-HartmanFrom: Xiaogang Chen <[email protected]>
commit 8eeddc0d4200762063e1c66b9cc63afa7b24ebf0 upstream.
During miration to vram prange->offset is valid after vram buffer is located, either use old one or allocate a new one. Move svm_range_vram_node_new before migrate for each vma to get valid prange->offset.
v2: squash in warning fix
--- drivers/gpu/drm/amd/amdkfd/kfd_migrate.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
drivers/gpu/drm/amd/amdkfd/kfd_migrate.c +9 -7
@@ -311,12 +311,6 @@ svm_migrate_copy_to_vram(struct amdgpu_d src = scratch; dst = (uint64_t *)(scratch + npages); - r =svm_range_vram_node_new (adev, prange, true); -if (r) { -dev_dbg (adev->dev,"fail %d to alloc vram\n" , r); - goto out; - } -amdgpu_res_first (prange->ttm_res, ttm_res_offset, npages <<PAGE_SHIFT , &cursor);for (i = j =0 ; i < npages; i++) {
@@ -397,7 +391,7 @@ out_free_vram_pages: migrate->dst[i + 3] = 0; }#endif -out: +return r; }
@@ -526,6 +520,12 @@ svm_migrate_ram_to_vram(struct svm_range start = prange->start <<PAGE_SHIFT ; end = (prange->last +1 ) <<PAGE_SHIFT ; + + r =svm_range_vram_node_new (adev, prange, true); +if (r) { +dev_dbg (adev->dev,"fail %ld to alloc vram\n" , r); +return r; + } ttm_res_offset = prange->offset <<PAGE_SHIFT ;for (addr = start; addr < end;) {
@@ -549,6 +549,8 @@ svm_migrate_ram_to_vram(struct svm_rangeif (cpages) prange->actual_loc = best_loc; +else +svm_range_vram_node_free (prange);return r <0 ? r :0 ; }
Greg Kroah-Hartman
maintainerPATCH 180/181 hsr: ratelimit only when errors are printed
In reply to Greg Kroah-HartmanFrom: Matthieu Baerts <[email protected]>
commit 1b0120e4db0bf2838d1ce741195ce4b7cc100b91 upstream.
Recently, when automatically merging -net and net-next in MPTCP devel tree, our CI reported [1] a conflict in hsr, the same as the one reported by Stephen in netdev [2].
When looking at the conflict, I noticed it is in fact the v1 [3] that has been applied in -net and the v2 [4] in net-next. Maybe the v1 was applied by accident.
As mentioned by Jakub Kicinski [5], the new condition makes more sense before the net_ratelimit(), not to update net_ratelimit's state which is unnecessary if we're not going to print either way.
Here, this modification applies the v2 but in -net.
--- net/hsr/hsr_framereg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/hsr/hsr_framereg.c +1 -1
@@ -422,7 +422,7 @@ void hsr_addr_subst_dest(struct hsr_node node_dst =find_node_by_addr_A (&port->hsr->node_db,eth_hdr (skb)->h_dest);if (!node_dst) { -if (net_ratelimit () && port->hsr->prot_version !=PRP_V1 ) +if (port->hsr->prot_version !=PRP_V1 &&net_ratelimit ())netdev_err (skb->dev,"%s: Unknown node\n" , __func__);return ; }
Greg Kroah-Hartman
maintainerPATCH 181/181 x86/PVH: avoid 32-bit build warning when obtaining VGA console info
In reply to Greg Kroah-HartmanFrom: Jan Beulich <[email protected]>
commit aadbd07ff8a75ed342388846da78dfaddb8b106a upstream.
In the commit referenced below I failed to pay attention to this code also being buildable as 32-bit. Adjust the type of "ret" - there's no real need for it to be wider than 32 bits.
--- arch/x86/xen/enlighten_pvh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/xen/enlighten_pvh.c +1 -1
@@ -48,7 +48,7 @@ void __init xen_pvh_init(struct boot_parstruct xen_platform_op op = { .cmd = XENPF_get_dom0_console, }; -long ret =HYPERVISOR_platform_op (&op); +int ret =HYPERVISOR_platform_op (&op);if (ret >0 ) xen_init_vga(&op.u.dom0_console,
Quoted 7 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.23 release. There are 181 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 Wed, 05 Apr 2023 14:03:18 +0000. Anything received after that time might be too late.
Hi Greg
6.1.23-rc1
compiles, boots and runs here on x86_64
(AMD Ryzen 5 PRO 4650G, Slackware64-15.0)
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.23 release. There are 181 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 Wed, 05 Apr 2023 14:03:18 +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.1.23-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Hi Greg
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.23 release. There are 181 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 Wed, 05 Apr 2023 14:03:18 +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.1.23-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
greg k-h
6.1.23-rc1 tested.
x86_64
Build successfully completed.
Boot successfully completed.
No dmesg regressions.
Video output normal.
Sound output normal.
Lenovo ThinkPad X1 Carbon Gen10(Intel i7-1260P, arch linux)
Thanks
Hi,
Quoted 9 lines
This is the start of the stable review cycle for the 6.1.23 release. There are 181 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 Wed, 05 Apr 2023 14:03:18 +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.1.23-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
greg k-h
fstests btrfs/056 triggered a panic for 6.1.23-rc1, but the panic does not happen on 6.1.22.
the patch *1 dropped in 6.1.9-rc is added to 6.1.231-rc1 again. *1 Subject: blk-mq: move the srcu_struct used for quiescing to the tagset
we need more patches because this issue does not happen(is fixed) in upstream.
so many new bug-fix patch depends on it, so it is not good to just drop it.
Best Regards
Wang Yugui ([email protected])
2023/04/04
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.23 release. There are 181 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 Wed, 05 Apr 2023 14:03:18 +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.1.23-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.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 5 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.23 release. There are 181 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.
Successfully cross-compiled for arm64 (bcm2711_defconfig, GCC 10.2.0) and powerpc (ps3_defconfig, GCC 12.2.0).
Signature · 1 line
An old man doll... just what I always wanted! - Clara
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.23 release. There are 181 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 Wed, 05 Apr 2023 14:03:18 +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.1.23-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v6.1:
11 builds: 11 pass, 0 fail
28 boots: 28 pass, 0 fail
130 tests: 130 pass, 0 failLinux version: 6.1.23-rc1-g01cd0041b7a5
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra194-p2972-0000, tegra194-p3509-0000+p3668-0000,
tegra20-ventana, tegra210-p2371-2180,
tegra210-p3450-0000, tegra30-cardhu-a04Jon
Hello Greg,
Quoted 10 lines
From: Greg Kroah-Hartman <[email protected]>
Sent: Monday, April 3, 2023 3:07 PMThis is the start of the stable review cycle for the 6.1.23 release. There are 181 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 Wed, 05 Apr 2023 14:03:18 +0000. Anything received after that time might be too late.
CIP configurations built and booted with Linux 6.1.23-rc1 (01cd0041b7a5):
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/pipelines/826566693
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/commits/linux-6.1.y
Kind regards, Chris
Quoted 7 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.23 release. There are 181 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 Wed, 05 Apr 2023 14:03:18 +0000. Anything received after that time might be too late.
On our RISC-V stuff, looks as per usual.
Thanks,
Conor.
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.23 release. There are 181 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 Wed, 05 Apr 2023 14:03:18 +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.1.23-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
## Build
* kernel: 6.1.23-rc1
* git: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc
* git branch: linux-6.1.y
* git commit: 01cd0041b7a5a573cba99332d1c30a82999d7fc1
* git describe: v6.1.22-182-g01cd0041b7a5
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.1.y/build/v6.1.22-182-g01cd0041b7a5
## Test Regressions (compared to v6.1.22)
## Metric Regressions (compared to v6.1.22)
## Test Fixes (compared to v6.1.22)
## Metric Fixes (compared to v6.1.22)
## Test result summary
total: 168890, pass: 147321, fail: 4018, skip: 17196, xfail: 355
## Build Summary
* arc: 5 total, 5 passed, 0 failed
* arm: 149 total, 148 passed, 1 failed
* arm64: 52 total, 51 passed, 1 failed
* i386: 39 total, 36 passed, 3 failed
* mips: 30 total, 28 passed, 2 failed
* parisc: 8 total, 8 passed, 0 failed
* powerpc: 38 total, 36 passed, 2 failed
* riscv: 16 total, 15 passed, 1 failed
* s390: 16 total, 16 passed, 0 failed
* sh: 14 total, 12 passed, 2 failed
* sparc: 8 total, 8 passed, 0 failed
* x86_64: 44 total, 44 passed, 0 failed
## Test suites summary
* boot
* fwts
* igt-gpu-tools
* kselftest-android
* kselftest-arm64
* kselftest-breakpoints
* kselftest-capabilities
* kselftest-cgroup
* kselftest-clone3
* kselftest-core
* kselftest-cpu-hotplug
* kselftest-cpufreq
* kselftest-drivers-dma-buf
* kselftest-efivarfs
* kselftest-filesystems
* kselftest-filesystems-binderfs
* kselftest-firmware
* kselftest-fpu
* kselftest-ftrace
* kselftest-futex
* kselftest-gpio
* kselftest-intel_pstate
* kselftest-ipc
* kselftest-ir
* kselftest-kcmp
* kselftest-kexec
* kselftest-kvm
* kselftest-lib
* kselftest-livepatch
* kselftest-membarrier
* kselftest-memfd
* kselftest-memory-hotplug
* kselftest-mincore
* kselftest-mount
* kselftest-mqueue
* kselftest-net
* kselftest-net-forwarding
* kselftest-net-mptcp
* kselftest-netfilter
* kselftest-nsfs
* kselftest-openat2
* kselftest-pid_namespace
* kselftest-pidfd
* kselftest-proc
* kselftest-pstore
* kselftest-ptrace
* kselftest-rseq
* kselftest-rtc
* kselftest-seccomp
* kselftest-sigaltstack
* kselftest-size
* kselftest-splice
* kselftest-static_keys
* kselftest-sync
* kselftest-sysctl
* kselftest-tc-testing
* kselftest-timens
* kselftest-timers
* kselftest-tmpfs
* kselftest-tpm2
* kselftest-user
* kselftest-vm
* kselftest-x86
* kselftest-zram
* kunit
* kvm-unit-tests
* libgpiod
* libhugetlbfs
* log-parser-boot
* log-parser-test
* ltp-cap_bounds
* ltp-commands
* ltp-containers
* ltp-controllers
* ltp-cpuhotplug
* ltp-crypto
* ltp-cve
* ltp-dio
* ltp-fcntl-locktests
* ltp-filecaps
* ltp-fs
* ltp-fs_bind
* ltp-fs_perms_simple
* ltp-fsx
* ltp-hugetlb
* ltp-io
* ltp-ipc
* ltp-math
* ltp-mm
* ltp-nptl
* ltp-open-posix-tests
* ltp-pty
* ltp-sched
* ltp-securebits
* ltp-smoke
* ltp-syscalls
* ltp-tracing
* network-basic-tests
* perf
* rcutorture
* v4l2-compliance
* vdso
--
Linaro LKFT
https://lkft.linaro.org
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.23 release. There are 181 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 Wed, 05 Apr 2023 14:03:18 +0000. Anything received after that time might be too late.
FWIW, this is for -rc1:
Build results:
total: 155 pass: 155 fail: 0 Qemu test results: total: 519 pass: 519 fail: 0
I'll test -rc2 tonight.
Guenter