mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-08-22 00:42:01 +02:00

If SER L2 occurs during the WoWLAN resume flow, the add interface flow is triggered by ieee80211_reconfig(). However, due to rtw89_wow_resume() return failure, it will cause the add interface flow to be executed again, resulting in a double add list and causing a kernel panic. Therefore, we have added a check to prevent double adding of the list. list_add double add: new=ffff99d6992e2010, prev=ffff99d6992e2010, next=ffff99d695302628. ------------[ cut here ]------------ kernel BUG at lib/list_debug.c:37! invalid opcode: 0000 [#1] PREEMPT SMP NOPTI CPU: 0 PID: 9 Comm: kworker/0:1 Tainted: G W O 6.6.30-02659-gc18865c4dfbd #1 770df2933251a0e3c888ba69d1053a817a6376a7 Hardware name: HP Grunt/Grunt, BIOS Google_Grunt.11031.169.0 06/24/2021 Workqueue: events_freezable ieee80211_restart_work [mac80211] RIP: 0010:__list_add_valid_or_report+0x5e/0xb0 Code: c7 74 18 48 39 ce 74 13 b0 01 59 5a 5e 5f 41 58 41 59 41 5a 5d e9 e2 d6 03 00 cc 48 c7 c7 8d 4f 17 83 48 89 c2 e8 02 c0 00 00 <0f> 0b 48 c7 c7 aa 8c 1c 83 e8 f4 bf 00 00 0f 0b 48 c7 c7 c8 bc 12 RSP: 0018:ffffa91b8007bc50 EFLAGS: 00010246 RAX: 0000000000000058 RBX: ffff99d6992e0900 RCX: a014d76c70ef3900 RDX: ffffa91b8007bae8 RSI: 00000000ffffdfff RDI: 0000000000000001 RBP: ffffa91b8007bc88 R08: 0000000000000000 R09: ffffa91b8007bae0 R10: 00000000ffffdfff R11: ffffffff83a79800 R12: ffff99d695302060 R13: ffff99d695300900 R14: ffff99d6992e1be0 R15: ffff99d6992e2010 FS: 0000000000000000(0000) GS:ffff99d6aac00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000078fbdba43480 CR3: 000000010e464000 CR4: 00000000001506f0 Call Trace: <TASK> ? __die_body+0x1f/0x70 ? die+0x3d/0x60 ? do_trap+0xa4/0x110 ? __list_add_valid_or_report+0x5e/0xb0 ? do_error_trap+0x6d/0x90 ? __list_add_valid_or_report+0x5e/0xb0 ? handle_invalid_op+0x30/0x40 ? __list_add_valid_or_report+0x5e/0xb0 ? exc_invalid_op+0x3c/0x50 ? asm_exc_invalid_op+0x16/0x20 ? __list_add_valid_or_report+0x5e/0xb0 rtw89_ops_add_interface+0x309/0x310 [rtw89_core 7c32b1ee6854761c0321027c8a58c5160e41f48f] drv_add_interface+0x5c/0x130 [mac80211 83e989e6e616bd5b4b8a2b0a9f9352a2c385a3bc] ieee80211_reconfig+0x241/0x13d0 [mac80211 83e989e6e616bd5b4b8a2b0a9f9352a2c385a3bc] ? finish_wait+0x3e/0x90 ? synchronize_rcu_expedited+0x174/0x260 ? sync_rcu_exp_done_unlocked+0x50/0x50 ? wake_bit_function+0x40/0x40 ieee80211_restart_work+0xf0/0x140 [mac80211 83e989e6e616bd5b4b8a2b0a9f9352a2c385a3bc] process_scheduled_works+0x1e5/0x480 worker_thread+0xea/0x1e0 kthread+0xdb/0x110 ? move_linked_works+0x90/0x90 ? kthread_associate_blkcg+0xa0/0xa0 ret_from_fork+0x3b/0x50 ? kthread_associate_blkcg+0xa0/0xa0 ret_from_fork_asm+0x11/0x20 </TASK> Modules linked in: dm_integrity async_xor xor async_tx lz4 lz4_compress zstd zstd_compress zram zsmalloc rfcomm cmac uinput algif_hash algif_skcipher af_alg btusb btrtl iio_trig_hrtimer industrialio_sw_trigger btmtk industrialio_configfs btbcm btintel uvcvideo videobuf2_vmalloc iio_trig_sysfs videobuf2_memops videobuf2_v4l2 videobuf2_common uvc snd_hda_codec_hdmi veth snd_hda_intel snd_intel_dspcfg acpi_als snd_hda_codec industrialio_triggered_buffer kfifo_buf snd_hwdep industrialio i2c_piix4 snd_hda_core designware_i2s ip6table_nat snd_soc_max98357a xt_MASQUERADE xt_cgroup snd_soc_acp_rt5682_mach fuse rtw89_8922ae(O) rtw89_8922a(O) rtw89_pci(O) rtw89_core(O) 8021q mac80211(O) bluetooth ecdh_generic ecc cfg80211 r8152 mii joydev gsmi: Log Shutdown Reason 0x03 ---[ end trace 0000000000000000 ]--- Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Link: https://patch.msgid.link/20240731070506.46100-4-pkshih@realtek.com
82 lines
2.1 KiB
C
82 lines
2.1 KiB
C
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
|
* Copyright(c) 2019-2020 Realtek Corporation
|
|
*/
|
|
#ifndef __RTW89_UTIL_H__
|
|
#define __RTW89_UTIL_H__
|
|
|
|
#include "core.h"
|
|
|
|
#define RTW89_LINEAR_FRAC_BITS 3
|
|
|
|
#define rtw89_iterate_vifs_bh(rtwdev, iterator, data) \
|
|
ieee80211_iterate_active_interfaces_atomic((rtwdev)->hw, \
|
|
IEEE80211_IFACE_ITER_NORMAL, iterator, data)
|
|
|
|
/* call this function with rtwdev->mutex is held */
|
|
#define rtw89_for_each_rtwvif(rtwdev, rtwvif) \
|
|
list_for_each_entry(rtwvif, &(rtwdev)->rtwvifs_list, list)
|
|
|
|
/* Before adding rtwvif to list, we need to check if it already exist, beacase
|
|
* in some case such as SER L2 happen during WoWLAN flow, calling reconfig
|
|
* twice cause the list to be added twice.
|
|
*/
|
|
static inline bool rtw89_rtwvif_in_list(struct rtw89_dev *rtwdev,
|
|
struct rtw89_vif *new)
|
|
{
|
|
struct rtw89_vif *rtwvif;
|
|
|
|
lockdep_assert_held(&rtwdev->mutex);
|
|
|
|
rtw89_for_each_rtwvif(rtwdev, rtwvif)
|
|
if (rtwvif == new)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
/* The result of negative dividend and positive divisor is undefined, but it
|
|
* should be one case of round-down or round-up. So, make it round-down if the
|
|
* result is round-up.
|
|
* Note: the maximum value of divisor is 0x7FFF_FFFF, because we cast it to
|
|
* signed value to make compiler to use signed divide instruction.
|
|
*/
|
|
static inline s32 s32_div_u32_round_down(s32 dividend, u32 divisor, s32 *remainder)
|
|
{
|
|
s32 i_divisor = (s32)divisor;
|
|
s32 i_remainder;
|
|
s32 quotient;
|
|
|
|
quotient = dividend / i_divisor;
|
|
i_remainder = dividend % i_divisor;
|
|
|
|
if (i_remainder < 0) {
|
|
quotient--;
|
|
i_remainder += i_divisor;
|
|
}
|
|
|
|
if (remainder)
|
|
*remainder = i_remainder;
|
|
return quotient;
|
|
}
|
|
|
|
static inline s32 s32_div_u32_round_closest(s32 dividend, u32 divisor)
|
|
{
|
|
return s32_div_u32_round_down(dividend + divisor / 2, divisor, NULL);
|
|
}
|
|
|
|
static inline void ether_addr_copy_mask(u8 *dst, const u8 *src, u8 mask)
|
|
{
|
|
int i;
|
|
|
|
eth_zero_addr(dst);
|
|
for (i = 0; i < ETH_ALEN; i++) {
|
|
if (mask & BIT(i))
|
|
dst[i] = src[i];
|
|
}
|
|
}
|
|
|
|
u32 rtw89_linear_2_db(u64 linear);
|
|
u64 rtw89_db_2_linear(u32 db);
|
|
|
|
#endif
|