diff options
author | Bart Van Assche <bart.vanassche@sandisk.com> | 2016-06-10 14:08:25 -0400 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2016-06-17 20:03:42 -0400 |
commit | 37e07cdafc111dfb7ce27e70e73d900d7cf2920c (patch) | |
tree | 1d693b736273416355d3019250f81c757f2bba58 /drivers/infiniband | |
parent | 8c5122e45a10a9262f872b53f151a592e870f905 (diff) |
IB/cma: Make the code easier to verify
Static source code analysis tools like smatch cannot handle functions
that lock or not lock a mutex depending on the value of the arguments.
Hence inline the function cma_disable_callback(). Additionally, this
patch realizes a small performance optimization by reducing the number of
mutex_lock() and mutex_unlock() calls in the modified functions. With
this patch applied smatch no longer complains about source file cma.c.
Without this patch smatch reports the following for this source file:
drivers/infiniband/core/cma.c:1959: cma_req_handler() warn: inconsistent returns 'mutex:&listen_id->handler_mutex'.
Locked on: line 1880
line 1959
Unlocked on: line 1941
drivers/infiniband/core/cma.c:2112: iw_conn_req_handler() warn: inconsistent returns 'mutex:&listen_id->handler_mutex'.
Locked on: line 2048
Unlocked on: line 2112
Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Cc: Sean Hefty <sean.hefty@intel.com>
Cc: Steve Wise <swise@opengridcomputing.com>
Cc: Leon Romanovsky <leonro@mellanox.com>
Acked-by: Sean Hefty <sean.hefty@intel.com>
Reviewed-by: Steve Wise <swise@opengridcomputing.com>
Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/cma.c | 54 |
1 files changed, 26 insertions, 28 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index f0c91ba3178a..c58ee771baaa 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
@@ -708,17 +708,6 @@ static void cma_deref_id(struct rdma_id_private *id_priv) | |||
708 | complete(&id_priv->comp); | 708 | complete(&id_priv->comp); |
709 | } | 709 | } |
710 | 710 | ||
711 | static int cma_disable_callback(struct rdma_id_private *id_priv, | ||
712 | enum rdma_cm_state state) | ||
713 | { | ||
714 | mutex_lock(&id_priv->handler_mutex); | ||
715 | if (id_priv->state != state) { | ||
716 | mutex_unlock(&id_priv->handler_mutex); | ||
717 | return -EINVAL; | ||
718 | } | ||
719 | return 0; | ||
720 | } | ||
721 | |||
722 | struct rdma_cm_id *rdma_create_id(struct net *net, | 711 | struct rdma_cm_id *rdma_create_id(struct net *net, |
723 | rdma_cm_event_handler event_handler, | 712 | rdma_cm_event_handler event_handler, |
724 | void *context, enum rdma_port_space ps, | 713 | void *context, enum rdma_port_space ps, |
@@ -1671,11 +1660,12 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) | |||
1671 | struct rdma_cm_event event; | 1660 | struct rdma_cm_event event; |
1672 | int ret = 0; | 1661 | int ret = 0; |
1673 | 1662 | ||
1663 | mutex_lock(&id_priv->handler_mutex); | ||
1674 | if ((ib_event->event != IB_CM_TIMEWAIT_EXIT && | 1664 | if ((ib_event->event != IB_CM_TIMEWAIT_EXIT && |
1675 | cma_disable_callback(id_priv, RDMA_CM_CONNECT)) || | 1665 | id_priv->state != RDMA_CM_CONNECT) || |
1676 | (ib_event->event == IB_CM_TIMEWAIT_EXIT && | 1666 | (ib_event->event == IB_CM_TIMEWAIT_EXIT && |
1677 | cma_disable_callback(id_priv, RDMA_CM_DISCONNECT))) | 1667 | id_priv->state != RDMA_CM_DISCONNECT)) |
1678 | return 0; | 1668 | goto out; |
1679 | 1669 | ||
1680 | memset(&event, 0, sizeof event); | 1670 | memset(&event, 0, sizeof event); |
1681 | switch (ib_event->event) { | 1671 | switch (ib_event->event) { |
@@ -1870,7 +1860,7 @@ static int cma_check_req_qp_type(struct rdma_cm_id *id, struct ib_cm_event *ib_e | |||
1870 | 1860 | ||
1871 | static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) | 1861 | static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) |
1872 | { | 1862 | { |
1873 | struct rdma_id_private *listen_id, *conn_id; | 1863 | struct rdma_id_private *listen_id, *conn_id = NULL; |
1874 | struct rdma_cm_event event; | 1864 | struct rdma_cm_event event; |
1875 | struct net_device *net_dev; | 1865 | struct net_device *net_dev; |
1876 | int offset, ret; | 1866 | int offset, ret; |
@@ -1884,9 +1874,10 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) | |||
1884 | goto net_dev_put; | 1874 | goto net_dev_put; |
1885 | } | 1875 | } |
1886 | 1876 | ||
1887 | if (cma_disable_callback(listen_id, RDMA_CM_LISTEN)) { | 1877 | mutex_lock(&listen_id->handler_mutex); |
1878 | if (listen_id->state != RDMA_CM_LISTEN) { | ||
1888 | ret = -ECONNABORTED; | 1879 | ret = -ECONNABORTED; |
1889 | goto net_dev_put; | 1880 | goto err1; |
1890 | } | 1881 | } |
1891 | 1882 | ||
1892 | memset(&event, 0, sizeof event); | 1883 | memset(&event, 0, sizeof event); |
@@ -1976,8 +1967,9 @@ static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event) | |||
1976 | struct sockaddr *laddr = (struct sockaddr *)&iw_event->local_addr; | 1967 | struct sockaddr *laddr = (struct sockaddr *)&iw_event->local_addr; |
1977 | struct sockaddr *raddr = (struct sockaddr *)&iw_event->remote_addr; | 1968 | struct sockaddr *raddr = (struct sockaddr *)&iw_event->remote_addr; |
1978 | 1969 | ||
1979 | if (cma_disable_callback(id_priv, RDMA_CM_CONNECT)) | 1970 | mutex_lock(&id_priv->handler_mutex); |
1980 | return 0; | 1971 | if (id_priv->state != RDMA_CM_CONNECT) |
1972 | goto out; | ||
1981 | 1973 | ||
1982 | memset(&event, 0, sizeof event); | 1974 | memset(&event, 0, sizeof event); |
1983 | switch (iw_event->event) { | 1975 | switch (iw_event->event) { |
@@ -2029,6 +2021,7 @@ static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event) | |||
2029 | return ret; | 2021 | return ret; |
2030 | } | 2022 | } |
2031 | 2023 | ||
2024 | out: | ||
2032 | mutex_unlock(&id_priv->handler_mutex); | 2025 | mutex_unlock(&id_priv->handler_mutex); |
2033 | return ret; | 2026 | return ret; |
2034 | } | 2027 | } |
@@ -2039,13 +2032,15 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, | |||
2039 | struct rdma_cm_id *new_cm_id; | 2032 | struct rdma_cm_id *new_cm_id; |
2040 | struct rdma_id_private *listen_id, *conn_id; | 2033 | struct rdma_id_private *listen_id, *conn_id; |
2041 | struct rdma_cm_event event; | 2034 | struct rdma_cm_event event; |
2042 | int ret; | 2035 | int ret = -ECONNABORTED; |
2043 | struct sockaddr *laddr = (struct sockaddr *)&iw_event->local_addr; | 2036 | struct sockaddr *laddr = (struct sockaddr *)&iw_event->local_addr; |
2044 | struct sockaddr *raddr = (struct sockaddr *)&iw_event->remote_addr; | 2037 | struct sockaddr *raddr = (struct sockaddr *)&iw_event->remote_addr; |
2045 | 2038 | ||
2046 | listen_id = cm_id->context; | 2039 | listen_id = cm_id->context; |
2047 | if (cma_disable_callback(listen_id, RDMA_CM_LISTEN)) | 2040 | |
2048 | return -ECONNABORTED; | 2041 | mutex_lock(&listen_id->handler_mutex); |
2042 | if (listen_id->state != RDMA_CM_LISTEN) | ||
2043 | goto out; | ||
2049 | 2044 | ||
2050 | /* Create a new RDMA id for the new IW CM ID */ | 2045 | /* Create a new RDMA id for the new IW CM ID */ |
2051 | new_cm_id = rdma_create_id(listen_id->id.route.addr.dev_addr.net, | 2046 | new_cm_id = rdma_create_id(listen_id->id.route.addr.dev_addr.net, |
@@ -3216,8 +3211,9 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id, | |||
3216 | struct ib_cm_sidr_rep_event_param *rep = &ib_event->param.sidr_rep_rcvd; | 3211 | struct ib_cm_sidr_rep_event_param *rep = &ib_event->param.sidr_rep_rcvd; |
3217 | int ret = 0; | 3212 | int ret = 0; |
3218 | 3213 | ||
3219 | if (cma_disable_callback(id_priv, RDMA_CM_CONNECT)) | 3214 | mutex_lock(&id_priv->handler_mutex); |
3220 | return 0; | 3215 | if (id_priv->state != RDMA_CM_CONNECT) |
3216 | goto out; | ||
3221 | 3217 | ||
3222 | memset(&event, 0, sizeof event); | 3218 | memset(&event, 0, sizeof event); |
3223 | switch (ib_event->event) { | 3219 | switch (ib_event->event) { |
@@ -3673,12 +3669,13 @@ static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast) | |||
3673 | struct rdma_id_private *id_priv; | 3669 | struct rdma_id_private *id_priv; |
3674 | struct cma_multicast *mc = multicast->context; | 3670 | struct cma_multicast *mc = multicast->context; |
3675 | struct rdma_cm_event event; | 3671 | struct rdma_cm_event event; |
3676 | int ret; | 3672 | int ret = 0; |
3677 | 3673 | ||
3678 | id_priv = mc->id_priv; | 3674 | id_priv = mc->id_priv; |
3679 | if (cma_disable_callback(id_priv, RDMA_CM_ADDR_BOUND) && | 3675 | mutex_lock(&id_priv->handler_mutex); |
3680 | cma_disable_callback(id_priv, RDMA_CM_ADDR_RESOLVED)) | 3676 | if (id_priv->state != RDMA_CM_ADDR_BOUND && |
3681 | return 0; | 3677 | id_priv->state != RDMA_CM_ADDR_RESOLVED) |
3678 | goto out; | ||
3682 | 3679 | ||
3683 | if (!status) | 3680 | if (!status) |
3684 | status = cma_set_qkey(id_priv, be32_to_cpu(multicast->rec.qkey)); | 3681 | status = cma_set_qkey(id_priv, be32_to_cpu(multicast->rec.qkey)); |
@@ -3720,6 +3717,7 @@ static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast) | |||
3720 | return 0; | 3717 | return 0; |
3721 | } | 3718 | } |
3722 | 3719 | ||
3720 | out: | ||
3723 | mutex_unlock(&id_priv->handler_mutex); | 3721 | mutex_unlock(&id_priv->handler_mutex); |
3724 | return 0; | 3722 | return 0; |
3725 | } | 3723 | } |