Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma

Pull rdma fix from Doug Ledford:
"Much calmer week this week. Just one patch queued up:

The way the siw driver was locking around the traversal of the list of
ipv6 addresses on a device was causing a scheduling while atomic
issue. Bernard straightened it out by using the rtnl_lock"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma:
RDMA/siw: Fix IPv6 addr_list locking

+20 -11
+20 -11
drivers/infiniband/sw/siw/siw_cm.c
··· 1962 1962 struct sockaddr_in s_laddr, *s_raddr; 1963 1963 const struct in_ifaddr *ifa; 1964 1964 1965 + if (!in_dev) { 1966 + rv = -ENODEV; 1967 + goto out; 1968 + } 1965 1969 memcpy(&s_laddr, &id->local_addr, sizeof(s_laddr)); 1966 1970 s_raddr = (struct sockaddr_in *)&id->remote_addr; 1967 1971 ··· 1995 1991 struct sockaddr_in6 *s_laddr = &to_sockaddr_in6(id->local_addr), 1996 1992 *s_raddr = &to_sockaddr_in6(id->remote_addr); 1997 1993 1994 + if (!in6_dev) { 1995 + rv = -ENODEV; 1996 + goto out; 1997 + } 1998 1998 siw_dbg(id->device, 1999 1999 "laddr %pI6:%d, raddr %pI6:%d\n", 2000 2000 &s_laddr->sin6_addr, ntohs(s_laddr->sin6_port), 2001 2001 &s_raddr->sin6_addr, ntohs(s_raddr->sin6_port)); 2002 2002 2003 - read_lock_bh(&in6_dev->lock); 2003 + rtnl_lock(); 2004 2004 list_for_each_entry(ifp, &in6_dev->addr_list, if_list) { 2005 - struct sockaddr_in6 bind_addr; 2006 - 2005 + if (ifp->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED)) 2006 + continue; 2007 2007 if (ipv6_addr_any(&s_laddr->sin6_addr) || 2008 2008 ipv6_addr_equal(&s_laddr->sin6_addr, &ifp->addr)) { 2009 - bind_addr.sin6_family = AF_INET6; 2010 - bind_addr.sin6_port = s_laddr->sin6_port; 2011 - bind_addr.sin6_flowinfo = 0; 2012 - bind_addr.sin6_addr = ifp->addr; 2013 - bind_addr.sin6_scope_id = dev->ifindex; 2009 + struct sockaddr_in6 bind_addr = { 2010 + .sin6_family = AF_INET6, 2011 + .sin6_port = s_laddr->sin6_port, 2012 + .sin6_flowinfo = 0, 2013 + .sin6_addr = ifp->addr, 2014 + .sin6_scope_id = dev->ifindex }; 2014 2015 2015 2016 rv = siw_listen_address(id, backlog, 2016 2017 (struct sockaddr *)&bind_addr, ··· 2024 2015 listeners++; 2025 2016 } 2026 2017 } 2027 - read_unlock_bh(&in6_dev->lock); 2028 - 2018 + rtnl_unlock(); 2029 2019 in6_dev_put(in6_dev); 2030 2020 } else { 2031 - return -EAFNOSUPPORT; 2021 + rv = -EAFNOSUPPORT; 2032 2022 } 2023 + out: 2033 2024 if (listeners) 2034 2025 rv = 0; 2035 2026 else if (!rv)