Commit 48107c4e authored by Doug Ledford's avatar Doug Ledford

Merge tag 'rdma-rc-2017-07-26' of...

Merge tag 'rdma-rc-2017-07-26' of git://git.kernel.org/pub/scm/linux/kernel/git/leon/linux-rdma into leon-ipoib

IPoIB fixes for 4.13

The patchset provides various fixes for IPoIB. It is combination of
fixes to various issues discovered during verification along with
static checkers cleanup patches.

Most of the patches are from pre-git era and hence lack of Fixes lines.

There is one exception in this IPoIB group - addition of patch revert:
Revert "IB/core: Allow QP state transition from reset to error", but
it followed by proper fix to the annoying print, so I thought it is
appropriate to include it.
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parents 5db465f2 5dc78ad1
...@@ -895,7 +895,6 @@ static const struct { ...@@ -895,7 +895,6 @@ static const struct {
} qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = { } qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = {
[IB_QPS_RESET] = { [IB_QPS_RESET] = {
[IB_QPS_RESET] = { .valid = 1 }, [IB_QPS_RESET] = { .valid = 1 },
[IB_QPS_ERR] = { .valid = 1 },
[IB_QPS_INIT] = { [IB_QPS_INIT] = {
.valid = 1, .valid = 1,
.req_param = { .req_param = {
......
...@@ -336,6 +336,7 @@ struct ipoib_dev_priv { ...@@ -336,6 +336,7 @@ struct ipoib_dev_priv {
unsigned long flags; unsigned long flags;
struct rw_semaphore vlan_rwsem; struct rw_semaphore vlan_rwsem;
struct mutex mcast_mutex;
struct rb_root path_tree; struct rb_root path_tree;
struct list_head path_list; struct list_head path_list;
......
...@@ -511,7 +511,6 @@ static int ipoib_cm_rx_handler(struct ib_cm_id *cm_id, ...@@ -511,7 +511,6 @@ static int ipoib_cm_rx_handler(struct ib_cm_id *cm_id,
case IB_CM_REQ_RECEIVED: case IB_CM_REQ_RECEIVED:
return ipoib_cm_req_handler(cm_id, event); return ipoib_cm_req_handler(cm_id, event);
case IB_CM_DREQ_RECEIVED: case IB_CM_DREQ_RECEIVED:
p = cm_id->context;
ib_send_cm_drep(cm_id, NULL, 0); ib_send_cm_drep(cm_id, NULL, 0);
/* Fall through */ /* Fall through */
case IB_CM_REJ_RECEIVED: case IB_CM_REJ_RECEIVED:
......
...@@ -52,7 +52,8 @@ static const struct ipoib_stats ipoib_gstrings_stats[] = { ...@@ -52,7 +52,8 @@ static const struct ipoib_stats ipoib_gstrings_stats[] = {
IPOIB_NETDEV_STAT(tx_bytes), IPOIB_NETDEV_STAT(tx_bytes),
IPOIB_NETDEV_STAT(tx_errors), IPOIB_NETDEV_STAT(tx_errors),
IPOIB_NETDEV_STAT(rx_dropped), IPOIB_NETDEV_STAT(rx_dropped),
IPOIB_NETDEV_STAT(tx_dropped) IPOIB_NETDEV_STAT(tx_dropped),
IPOIB_NETDEV_STAT(multicast),
}; };
#define IPOIB_GLOBAL_STATS_LEN ARRAY_SIZE(ipoib_gstrings_stats) #define IPOIB_GLOBAL_STATS_LEN ARRAY_SIZE(ipoib_gstrings_stats)
......
...@@ -256,6 +256,8 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) ...@@ -256,6 +256,8 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
++dev->stats.rx_packets; ++dev->stats.rx_packets;
dev->stats.rx_bytes += skb->len; dev->stats.rx_bytes += skb->len;
if (skb->pkt_type == PACKET_MULTICAST)
dev->stats.multicast++;
skb->dev = dev; skb->dev = dev;
if ((dev->features & NETIF_F_RXCSUM) && if ((dev->features & NETIF_F_RXCSUM) &&
...@@ -709,6 +711,27 @@ static int recvs_pending(struct net_device *dev) ...@@ -709,6 +711,27 @@ static int recvs_pending(struct net_device *dev)
return pending; return pending;
} }
static void check_qp_movement_and_print(struct ipoib_dev_priv *priv,
struct ib_qp *qp,
enum ib_qp_state new_state)
{
struct ib_qp_attr qp_attr;
struct ib_qp_init_attr query_init_attr;
int ret;
ret = ib_query_qp(qp, &qp_attr, IB_QP_STATE, &query_init_attr);
if (ret) {
ipoib_warn(priv, "%s: Failed to query QP\n", __func__);
return;
}
/* print according to the new-state and the previous state.*/
if (new_state == IB_QPS_ERR && qp_attr.qp_state == IB_QPS_RESET)
ipoib_dbg(priv, "Failed modify QP, IB_QPS_RESET to IB_QPS_ERR, acceptable\n");
else
ipoib_warn(priv, "Failed to modify QP to state: %d from state: %d\n",
new_state, qp_attr.qp_state);
}
int ipoib_ib_dev_stop_default(struct net_device *dev) int ipoib_ib_dev_stop_default(struct net_device *dev)
{ {
struct ipoib_dev_priv *priv = ipoib_priv(dev); struct ipoib_dev_priv *priv = ipoib_priv(dev);
...@@ -728,7 +751,7 @@ int ipoib_ib_dev_stop_default(struct net_device *dev) ...@@ -728,7 +751,7 @@ int ipoib_ib_dev_stop_default(struct net_device *dev)
*/ */
qp_attr.qp_state = IB_QPS_ERR; qp_attr.qp_state = IB_QPS_ERR;
if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE)) if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE))
ipoib_warn(priv, "Failed to modify QP to ERROR state\n"); check_qp_movement_and_print(priv, priv->qp, IB_QPS_ERR);
/* Wait for all sends and receives to complete */ /* Wait for all sends and receives to complete */
begin = jiffies; begin = jiffies;
......
...@@ -1560,6 +1560,7 @@ static void ipoib_flush_neighs(struct ipoib_dev_priv *priv) ...@@ -1560,6 +1560,7 @@ static void ipoib_flush_neighs(struct ipoib_dev_priv *priv)
int i, wait_flushed = 0; int i, wait_flushed = 0;
init_completion(&priv->ntbl.flushed); init_completion(&priv->ntbl.flushed);
set_bit(IPOIB_NEIGH_TBL_FLUSH, &priv->flags);
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
...@@ -1604,7 +1605,6 @@ static void ipoib_neigh_hash_uninit(struct net_device *dev) ...@@ -1604,7 +1605,6 @@ static void ipoib_neigh_hash_uninit(struct net_device *dev)
ipoib_dbg(priv, "ipoib_neigh_hash_uninit\n"); ipoib_dbg(priv, "ipoib_neigh_hash_uninit\n");
init_completion(&priv->ntbl.deleted); init_completion(&priv->ntbl.deleted);
set_bit(IPOIB_NEIGH_TBL_FLUSH, &priv->flags);
/* Stop GC if called at init fail need to cancel work */ /* Stop GC if called at init fail need to cancel work */
stopped = test_and_set_bit(IPOIB_STOP_NEIGH_GC, &priv->flags); stopped = test_and_set_bit(IPOIB_STOP_NEIGH_GC, &priv->flags);
...@@ -1847,6 +1847,7 @@ static const struct net_device_ops ipoib_netdev_ops_vf = { ...@@ -1847,6 +1847,7 @@ static const struct net_device_ops ipoib_netdev_ops_vf = {
.ndo_tx_timeout = ipoib_timeout, .ndo_tx_timeout = ipoib_timeout,
.ndo_set_rx_mode = ipoib_set_mcast_list, .ndo_set_rx_mode = ipoib_set_mcast_list,
.ndo_get_iflink = ipoib_get_iflink, .ndo_get_iflink = ipoib_get_iflink,
.ndo_get_stats64 = ipoib_get_stats,
}; };
void ipoib_setup_common(struct net_device *dev) void ipoib_setup_common(struct net_device *dev)
...@@ -1877,6 +1878,7 @@ static void ipoib_build_priv(struct net_device *dev) ...@@ -1877,6 +1878,7 @@ static void ipoib_build_priv(struct net_device *dev)
priv->dev = dev; priv->dev = dev;
spin_lock_init(&priv->lock); spin_lock_init(&priv->lock);
init_rwsem(&priv->vlan_rwsem); init_rwsem(&priv->vlan_rwsem);
mutex_init(&priv->mcast_mutex);
INIT_LIST_HEAD(&priv->path_list); INIT_LIST_HEAD(&priv->path_list);
INIT_LIST_HEAD(&priv->child_intfs); INIT_LIST_HEAD(&priv->child_intfs);
...@@ -2173,14 +2175,14 @@ static struct net_device *ipoib_add_port(const char *format, ...@@ -2173,14 +2175,14 @@ static struct net_device *ipoib_add_port(const char *format,
priv->dev->dev_id = port - 1; priv->dev->dev_id = port - 1;
result = ib_query_port(hca, port, &attr); result = ib_query_port(hca, port, &attr);
if (!result) if (result) {
priv->max_ib_mtu = ib_mtu_enum_to_int(attr.max_mtu);
else {
printk(KERN_WARNING "%s: ib_query_port %d failed\n", printk(KERN_WARNING "%s: ib_query_port %d failed\n",
hca->name, port); hca->name, port);
goto device_init_failed; goto device_init_failed;
} }
priv->max_ib_mtu = ib_mtu_enum_to_int(attr.max_mtu);
/* MTU will be reset when mcast join happens */ /* MTU will be reset when mcast join happens */
priv->dev->mtu = IPOIB_UD_MTU(priv->max_ib_mtu); priv->dev->mtu = IPOIB_UD_MTU(priv->max_ib_mtu);
priv->mcast_mtu = priv->admin_mtu = priv->dev->mtu; priv->mcast_mtu = priv->admin_mtu = priv->dev->mtu;
...@@ -2211,12 +2213,14 @@ static struct net_device *ipoib_add_port(const char *format, ...@@ -2211,12 +2213,14 @@ static struct net_device *ipoib_add_port(const char *format,
printk(KERN_WARNING "%s: ib_query_gid port %d failed (ret = %d)\n", printk(KERN_WARNING "%s: ib_query_gid port %d failed (ret = %d)\n",
hca->name, port, result); hca->name, port, result);
goto device_init_failed; goto device_init_failed;
} else }
memcpy(priv->dev->dev_addr + 4, priv->local_gid.raw, sizeof (union ib_gid));
memcpy(priv->dev->dev_addr + 4, priv->local_gid.raw,
sizeof(union ib_gid));
set_bit(IPOIB_FLAG_DEV_ADDR_SET, &priv->flags); set_bit(IPOIB_FLAG_DEV_ADDR_SET, &priv->flags);
result = ipoib_dev_init(priv->dev, hca, port); result = ipoib_dev_init(priv->dev, hca, port);
if (result < 0) { if (result) {
printk(KERN_WARNING "%s: failed to initialize port %d (ret = %d)\n", printk(KERN_WARNING "%s: failed to initialize port %d (ret = %d)\n",
hca->name, port, result); hca->name, port, result);
goto device_init_failed; goto device_init_failed;
...@@ -2365,6 +2369,7 @@ static int __init ipoib_init_module(void) ...@@ -2365,6 +2369,7 @@ static int __init ipoib_init_module(void)
ipoib_sendq_size = max3(ipoib_sendq_size, 2 * MAX_SEND_CQE, IPOIB_MIN_QUEUE_SIZE); ipoib_sendq_size = max3(ipoib_sendq_size, 2 * MAX_SEND_CQE, IPOIB_MIN_QUEUE_SIZE);
#ifdef CONFIG_INFINIBAND_IPOIB_CM #ifdef CONFIG_INFINIBAND_IPOIB_CM
ipoib_max_conn_qp = min(ipoib_max_conn_qp, IPOIB_CM_MAX_CONN_QP); ipoib_max_conn_qp = min(ipoib_max_conn_qp, IPOIB_CM_MAX_CONN_QP);
ipoib_max_conn_qp = max(ipoib_max_conn_qp, 0);
#endif #endif
/* /*
......
...@@ -684,15 +684,10 @@ void ipoib_mcast_start_thread(struct net_device *dev) ...@@ -684,15 +684,10 @@ void ipoib_mcast_start_thread(struct net_device *dev)
int ipoib_mcast_stop_thread(struct net_device *dev) int ipoib_mcast_stop_thread(struct net_device *dev)
{ {
struct ipoib_dev_priv *priv = ipoib_priv(dev); struct ipoib_dev_priv *priv = ipoib_priv(dev);
unsigned long flags;
ipoib_dbg_mcast(priv, "stopping multicast thread\n"); ipoib_dbg_mcast(priv, "stopping multicast thread\n");
spin_lock_irqsave(&priv->lock, flags); cancel_delayed_work_sync(&priv->mcast_task);
cancel_delayed_work(&priv->mcast_task);
spin_unlock_irqrestore(&priv->lock, flags);
flush_workqueue(priv->wq);
return 0; return 0;
} }
...@@ -748,6 +743,14 @@ void ipoib_mcast_remove_list(struct list_head *remove_list) ...@@ -748,6 +743,14 @@ void ipoib_mcast_remove_list(struct list_head *remove_list)
{ {
struct ipoib_mcast *mcast, *tmcast; struct ipoib_mcast *mcast, *tmcast;
/*
* make sure the in-flight joins have finished before we attempt
* to leave
*/
list_for_each_entry_safe(mcast, tmcast, remove_list, list)
if (test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags))
wait_for_completion(&mcast->done);
list_for_each_entry_safe(mcast, tmcast, remove_list, list) { list_for_each_entry_safe(mcast, tmcast, remove_list, list) {
ipoib_mcast_leave(mcast->dev, mcast); ipoib_mcast_leave(mcast->dev, mcast);
ipoib_mcast_free(mcast); ipoib_mcast_free(mcast);
...@@ -838,6 +841,7 @@ void ipoib_mcast_dev_flush(struct net_device *dev) ...@@ -838,6 +841,7 @@ void ipoib_mcast_dev_flush(struct net_device *dev)
struct ipoib_mcast *mcast, *tmcast; struct ipoib_mcast *mcast, *tmcast;
unsigned long flags; unsigned long flags;
mutex_lock(&priv->mcast_mutex);
ipoib_dbg_mcast(priv, "flushing multicast list\n"); ipoib_dbg_mcast(priv, "flushing multicast list\n");
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
...@@ -856,15 +860,8 @@ void ipoib_mcast_dev_flush(struct net_device *dev) ...@@ -856,15 +860,8 @@ void ipoib_mcast_dev_flush(struct net_device *dev)
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
/*
* make sure the in-flight joins have finished before we attempt
* to leave
*/
list_for_each_entry_safe(mcast, tmcast, &remove_list, list)
if (test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags))
wait_for_completion(&mcast->done);
ipoib_mcast_remove_list(&remove_list); ipoib_mcast_remove_list(&remove_list);
mutex_unlock(&priv->mcast_mutex);
} }
static int ipoib_mcast_addr_is_valid(const u8 *addr, const u8 *broadcast) static int ipoib_mcast_addr_is_valid(const u8 *addr, const u8 *broadcast)
...@@ -982,14 +979,6 @@ void ipoib_mcast_restart_task(struct work_struct *work) ...@@ -982,14 +979,6 @@ void ipoib_mcast_restart_task(struct work_struct *work)
netif_addr_unlock(dev); netif_addr_unlock(dev);
local_irq_restore(flags); local_irq_restore(flags);
/*
* make sure the in-flight joins have finished before we attempt
* to leave
*/
list_for_each_entry_safe(mcast, tmcast, &remove_list, list)
if (test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags))
wait_for_completion(&mcast->done);
ipoib_mcast_remove_list(&remove_list); ipoib_mcast_remove_list(&remove_list);
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment