ipmi: msghandler: Pass lockdep expression to RCU lists
PATCH RESEND v3 1/1 ipmi: msghandler: Pass lockdep expression to RCU lists
intf->cmd_rcvrs is traversed with list_for_each_entry_rcu outside an RCU read-side critical section but under the protection of intf->cmd_rcvrs_mutex.
ipmi_interfaces is traversed using list_for_each_entry_rcu outside an RCU read-side critical section but under the protection of ipmi_interfaces_mutex.
Hence, add the corresponding lockdep expression to the list traversal primitive to silence false-positive lockdep warnings, and harden RCU lists.
Add macro for the corresponding lockdep expression to make the code clean and concise.
---
v3:
- Remove rcu_read_lock_held() from lockdep expression since it is implicitly checked.
- Remove unintended macro usage.
v2:
- Fix sparse error
CHECK: Alignment should match open parenthesis
drivers/char/ipmi/ipmi_msghandler.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
drivers/char/ipmi/ipmi_msghandler.c +10 -4
@@ -618,6 +618,8 @@ static DEFINE_MUTEX(ipmidriver_mutex);static LIST_HEAD (ipmi_interfaces);static DEFINE_MUTEX (ipmi_interfaces_mutex); +#define ipmi_interfaces_mutex_held () \ + lockdep_is_held(&ipmi_interfaces_mutex)static struct srcu_struct ipmi_interfaces_srcu;/*
@@ -1321,7 +1323,8 @@ static void _ipmi_destroy_user(struct ipmi_user *user)* synchronize_srcu()) then free everything in that list. */ mutex_lock (&intf->cmd_rcvrs_mutex); -list_for_each_entry_rcu (rcvr, &intf->cmd_rcvrs, link) { +list_for_each_entry_rcu (rcvr, &intf->cmd_rcvrs, link, +lockdep_is_held (&intf->cmd_rcvrs_mutex)) {if (rcvr->user == user) {list_del_rcu (&rcvr->link); rcvr->next = rcvrs;
@@ -1599,7 +1602,8 @@ static struct cmd_rcvr *find_cmd_rcvr(struct ipmi_smi *intf, {struct cmd_rcvr *rcvr; -list_for_each_entry_rcu (rcvr, &intf->cmd_rcvrs, link) { +list_for_each_entry_rcu (rcvr, &intf->cmd_rcvrs, link, +lockdep_is_held (&intf->cmd_rcvrs_mutex)) {if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd) && (rcvr->chans & (1 << chan)))return rcvr;
@@ -1614,7 +1618,8 @@ static int is_cmd_rcvr_exclusive(struct ipmi_smi *intf, {struct cmd_rcvr *rcvr; -list_for_each_entry_rcu (rcvr, &intf->cmd_rcvrs, link) { +list_for_each_entry_rcu (rcvr, &intf->cmd_rcvrs, link, +lockdep_is_held (&intf->cmd_rcvrs_mutex)) {if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd) && (rcvr->chans & chans))return 0 ;
@@ -3450,7 +3455,8 @@ int ipmi_add_smi(struct module *owner,/* Look for a hole in the numbers. */ i =0 ; link = &ipmi_interfaces; -list_for_each_entry_rcu (tintf, &ipmi_interfaces, link) { +list_for_each_entry_rcu (tintf, &ipmi_interfaces, link, +ipmi_interfaces_mutex_held ()) {if (tintf->intf_num != i) { link = &tintf->link;break ;
Signature · 1 line
2.24.1