atlantic: fix deadlock at aq_nic_stop
stable inclusion from stable-v5.10.153 commit af7879529e5a859cb93a41b148d8d256046d1b28 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I64YCA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=af7879529e5a859cb93a41b148d8d256046d1b28 -------------------------------- [ Upstream commit 6960d133 ] NIC is stopped with rtnl_lock held, and during the stop it cancels the 'service_task' work and free irqs. However, if CONFIG_MACSEC is set, rtnl_lock is acquired both from aq_nic_service_task and aq_linkstate_threaded_isr. Then a deadlock happens if aq_nic_stop tries to cancel/disable them when they've already started their execution. As the deadlock is caused by rtnl_lock, it causes many other processes to stall, not only atlantic related stuff. Fix it by introducing a mutex that protects each NIC's macsec related data, and locking it instead of the rtnl_lock from the service task and the threaded IRQ. Before this patch, all macsec data was protected with rtnl_lock, but maybe not all of it needs to be protected. With this new mutex, further efforts can be made to limit the protected data only to that which requires it. However, probably it doesn't worth it because all macsec's data accesses are infrequent, and almost all are done from macsec_ops or ethtool callbacks, called holding rtnl_lock, so macsec_mutex won't never be much contended. The issue appeared repeteadly attaching and deattaching the NIC to a bond interface. Doing that after this patch I cannot reproduce the bug. Fixes: 62c1c2e6 ("net: atlantic: MACSec offload skeleton") Reported-by: NLi Liang <liali@redhat.com> Suggested-by: NAndrew Lunn <andrew@lunn.ch> Signed-off-by: NÍñigo Huguet <ihuguet@redhat.com> Reviewed-by: NIgor Russkikh <irusskikh@marvell.com> Signed-off-by: NDavid S. Miller <davem@davemloft.net> Signed-off-by: NSasha Levin <sashal@kernel.org> Signed-off-by: NLipeng Sang <sanglipeng1@jd.com>
Showing
想要评论请 注册 或 登录