Pull request for 5.3-rc6
- Fix locking on list traversal (siw) Signed-off-by: Doug Ledford <dledford@redhat.com> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEErmsb2hIrI7QmWxJ0uCajMw5XL90FAl1pQsMACgkQuCajMw5X L92NqBAAjgG/rV9RuUjxr4+tBkyp2OIDCma0bP8q5x5g6jBaaxgzrzZjwYf4W5ae MVbj7DIf+toAXm19+O5Kh+SjVKcCh0zcRlBbjqn8ZUtONFE4Dx2OsbYyPGA8SMP/ n+J5O7GtjuPSH+lF0IsrzO9dm4v2RLtL2iE9ryxvEjKWXqe/sxzBKgk3sMmYfKqZ eJQIcmDqdFjmmbrSTRKqPoHdGCAe1y9xDvo4FNr1Yv2Rk8ZSkL1J48QY7Cv6i9uU Z28VaMJRhh+qNalYV49yvwuwsvsNZpOlQv1/p/BK59TbfZCYa2/X9oTWLZO45nGE fD193+SEsBWE7x2nPRlBL1cGAojkgMi84O7thyngZP5z5W6etp9/LgYlDYo6NCBy FmBGAbt4dYEGChx8fIwoe6cDgEQLJL6NYu4GP/dkSW16WQB6c9DVE5+vyAe9idp+ f+Ou866LzHCSA3Fv4fOnf7ak3Q27s9QWu+zTBNH2BWGOCOQufExpIo0p8yskEhcJ n7n9XduRlnDAvgcACSlUGtoI4+cjLawF5RdDD5T5bMDj0RNc4gzcBwD8w6rHeET1 zitzS6C50+VFfF+GK/Bd8jL4kl0jb314fECOmJVilIY7rzlv/NSsKDbahr3v4qdn T8DkNT9ctRm4evP6XQdPQYlbHRkgBckN5HD/0VvLDckIpyHhzg8= =T0bq -----END PGP SIGNATURE----- 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
This commit is contained in:
Коммит
8fb8e9e462
|
@ -1962,6 +1962,10 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
|
||||||
struct sockaddr_in s_laddr, *s_raddr;
|
struct sockaddr_in s_laddr, *s_raddr;
|
||||||
const struct in_ifaddr *ifa;
|
const struct in_ifaddr *ifa;
|
||||||
|
|
||||||
|
if (!in_dev) {
|
||||||
|
rv = -ENODEV;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
memcpy(&s_laddr, &id->local_addr, sizeof(s_laddr));
|
memcpy(&s_laddr, &id->local_addr, sizeof(s_laddr));
|
||||||
s_raddr = (struct sockaddr_in *)&id->remote_addr;
|
s_raddr = (struct sockaddr_in *)&id->remote_addr;
|
||||||
|
|
||||||
|
@ -1991,22 +1995,27 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
|
||||||
struct sockaddr_in6 *s_laddr = &to_sockaddr_in6(id->local_addr),
|
struct sockaddr_in6 *s_laddr = &to_sockaddr_in6(id->local_addr),
|
||||||
*s_raddr = &to_sockaddr_in6(id->remote_addr);
|
*s_raddr = &to_sockaddr_in6(id->remote_addr);
|
||||||
|
|
||||||
|
if (!in6_dev) {
|
||||||
|
rv = -ENODEV;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
siw_dbg(id->device,
|
siw_dbg(id->device,
|
||||||
"laddr %pI6:%d, raddr %pI6:%d\n",
|
"laddr %pI6:%d, raddr %pI6:%d\n",
|
||||||
&s_laddr->sin6_addr, ntohs(s_laddr->sin6_port),
|
&s_laddr->sin6_addr, ntohs(s_laddr->sin6_port),
|
||||||
&s_raddr->sin6_addr, ntohs(s_raddr->sin6_port));
|
&s_raddr->sin6_addr, ntohs(s_raddr->sin6_port));
|
||||||
|
|
||||||
read_lock_bh(&in6_dev->lock);
|
rtnl_lock();
|
||||||
list_for_each_entry(ifp, &in6_dev->addr_list, if_list) {
|
list_for_each_entry(ifp, &in6_dev->addr_list, if_list) {
|
||||||
struct sockaddr_in6 bind_addr;
|
if (ifp->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED))
|
||||||
|
continue;
|
||||||
if (ipv6_addr_any(&s_laddr->sin6_addr) ||
|
if (ipv6_addr_any(&s_laddr->sin6_addr) ||
|
||||||
ipv6_addr_equal(&s_laddr->sin6_addr, &ifp->addr)) {
|
ipv6_addr_equal(&s_laddr->sin6_addr, &ifp->addr)) {
|
||||||
bind_addr.sin6_family = AF_INET6;
|
struct sockaddr_in6 bind_addr = {
|
||||||
bind_addr.sin6_port = s_laddr->sin6_port;
|
.sin6_family = AF_INET6,
|
||||||
bind_addr.sin6_flowinfo = 0;
|
.sin6_port = s_laddr->sin6_port,
|
||||||
bind_addr.sin6_addr = ifp->addr;
|
.sin6_flowinfo = 0,
|
||||||
bind_addr.sin6_scope_id = dev->ifindex;
|
.sin6_addr = ifp->addr,
|
||||||
|
.sin6_scope_id = dev->ifindex };
|
||||||
|
|
||||||
rv = siw_listen_address(id, backlog,
|
rv = siw_listen_address(id, backlog,
|
||||||
(struct sockaddr *)&bind_addr,
|
(struct sockaddr *)&bind_addr,
|
||||||
|
@ -2015,12 +2024,12 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
|
||||||
listeners++;
|
listeners++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
read_unlock_bh(&in6_dev->lock);
|
rtnl_unlock();
|
||||||
|
|
||||||
in6_dev_put(in6_dev);
|
in6_dev_put(in6_dev);
|
||||||
} else {
|
} else {
|
||||||
return -EAFNOSUPPORT;
|
rv = -EAFNOSUPPORT;
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
if (listeners)
|
if (listeners)
|
||||||
rv = 0;
|
rv = 0;
|
||||||
else if (!rv)
|
else if (!rv)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче