Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband:
  IPoIB: Don't turn on carrier for a non-active port
  IB/mthca: Fix access to freed memory in catastrophic event handling
  mlx4_core: Pass cache line size to device FW
  RDMA/nes: Remove duplicate .ndo_set_mac_address field initialization
  IB/mad: Fix lock-lock-timer deadlock in RMPP code
This commit is contained in:
Linus Torvalds 2009-09-24 17:06:01 -07:00
commit d7757be133
5 changed files with 33 additions and 8 deletions

View file

@ -37,7 +37,8 @@
enum rmpp_state { enum rmpp_state {
RMPP_STATE_ACTIVE, RMPP_STATE_ACTIVE,
RMPP_STATE_TIMEOUT, RMPP_STATE_TIMEOUT,
RMPP_STATE_COMPLETE RMPP_STATE_COMPLETE,
RMPP_STATE_CANCELING
}; };
struct mad_rmpp_recv { struct mad_rmpp_recv {
@ -86,19 +87,23 @@ void ib_cancel_rmpp_recvs(struct ib_mad_agent_private *agent)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&agent->lock, flags); spin_lock_irqsave(&agent->lock, flags);
list_for_each_entry(rmpp_recv, &agent->rmpp_list, list) {
if (rmpp_recv->state != RMPP_STATE_COMPLETE)
ib_free_recv_mad(rmpp_recv->rmpp_wc);
rmpp_recv->state = RMPP_STATE_CANCELING;
}
spin_unlock_irqrestore(&agent->lock, flags);
list_for_each_entry(rmpp_recv, &agent->rmpp_list, list) { list_for_each_entry(rmpp_recv, &agent->rmpp_list, list) {
cancel_delayed_work(&rmpp_recv->timeout_work); cancel_delayed_work(&rmpp_recv->timeout_work);
cancel_delayed_work(&rmpp_recv->cleanup_work); cancel_delayed_work(&rmpp_recv->cleanup_work);
} }
spin_unlock_irqrestore(&agent->lock, flags);
flush_workqueue(agent->qp_info->port_priv->wq); flush_workqueue(agent->qp_info->port_priv->wq);
list_for_each_entry_safe(rmpp_recv, temp_rmpp_recv, list_for_each_entry_safe(rmpp_recv, temp_rmpp_recv,
&agent->rmpp_list, list) { &agent->rmpp_list, list) {
list_del(&rmpp_recv->list); list_del(&rmpp_recv->list);
if (rmpp_recv->state != RMPP_STATE_COMPLETE)
ib_free_recv_mad(rmpp_recv->rmpp_wc);
destroy_rmpp_recv(rmpp_recv); destroy_rmpp_recv(rmpp_recv);
} }
} }
@ -260,6 +265,10 @@ static void recv_cleanup_handler(struct work_struct *work)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&rmpp_recv->agent->lock, flags); spin_lock_irqsave(&rmpp_recv->agent->lock, flags);
if (rmpp_recv->state == RMPP_STATE_CANCELING) {
spin_unlock_irqrestore(&rmpp_recv->agent->lock, flags);
return;
}
list_del(&rmpp_recv->list); list_del(&rmpp_recv->list);
spin_unlock_irqrestore(&rmpp_recv->agent->lock, flags); spin_unlock_irqrestore(&rmpp_recv->agent->lock, flags);
destroy_rmpp_recv(rmpp_recv); destroy_rmpp_recv(rmpp_recv);

View file

@ -68,11 +68,16 @@ static void catas_reset(struct work_struct *work)
spin_unlock_irq(&catas_lock); spin_unlock_irq(&catas_lock);
list_for_each_entry_safe(dev, tmpdev, &tlist, catas_err.list) { list_for_each_entry_safe(dev, tmpdev, &tlist, catas_err.list) {
struct pci_dev *pdev = dev->pdev;
ret = __mthca_restart_one(dev->pdev); ret = __mthca_restart_one(dev->pdev);
/* 'dev' now is not valid */
if (ret) if (ret)
mthca_err(dev, "Reset failed (%d)\n", ret); printk(KERN_ERR "mthca %s: Reset failed (%d)\n",
else pci_name(pdev), ret);
mthca_dbg(dev, "Reset succeeded\n"); else {
struct mthca_dev *d = pci_get_drvdata(pdev);
mthca_dbg(d, "Reset succeeded\n");
}
} }
mutex_unlock(&mthca_device_mutex); mutex_unlock(&mthca_device_mutex);

View file

@ -1566,7 +1566,6 @@ static const struct net_device_ops nes_netdev_ops = {
.ndo_set_mac_address = nes_netdev_set_mac_address, .ndo_set_mac_address = nes_netdev_set_mac_address,
.ndo_set_multicast_list = nes_netdev_set_multicast_list, .ndo_set_multicast_list = nes_netdev_set_multicast_list,
.ndo_change_mtu = nes_netdev_change_mtu, .ndo_change_mtu = nes_netdev_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
.ndo_vlan_rx_register = nes_netdev_vlan_rx_register, .ndo_vlan_rx_register = nes_netdev_vlan_rx_register,
}; };

View file

@ -362,12 +362,19 @@ void ipoib_mcast_carrier_on_task(struct work_struct *work)
{ {
struct ipoib_dev_priv *priv = container_of(work, struct ipoib_dev_priv, struct ipoib_dev_priv *priv = container_of(work, struct ipoib_dev_priv,
carrier_on_task); carrier_on_task);
struct ib_port_attr attr;
/* /*
* Take rtnl_lock to avoid racing with ipoib_stop() and * Take rtnl_lock to avoid racing with ipoib_stop() and
* turning the carrier back on while a device is being * turning the carrier back on while a device is being
* removed. * removed.
*/ */
if (ib_query_port(priv->ca, priv->port, &attr) ||
attr.state != IB_PORT_ACTIVE) {
ipoib_dbg(priv, "Keeping carrier off until IB port is active\n");
return;
}
rtnl_lock(); rtnl_lock();
netif_carrier_on(priv->dev); netif_carrier_on(priv->dev);
rtnl_unlock(); rtnl_unlock();

View file

@ -33,6 +33,7 @@
*/ */
#include <linux/mlx4/cmd.h> #include <linux/mlx4/cmd.h>
#include <linux/cache.h>
#include "fw.h" #include "fw.h"
#include "icm.h" #include "icm.h"
@ -698,6 +699,7 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param)
#define INIT_HCA_IN_SIZE 0x200 #define INIT_HCA_IN_SIZE 0x200
#define INIT_HCA_VERSION_OFFSET 0x000 #define INIT_HCA_VERSION_OFFSET 0x000
#define INIT_HCA_VERSION 2 #define INIT_HCA_VERSION 2
#define INIT_HCA_CACHELINE_SZ_OFFSET 0x0e
#define INIT_HCA_FLAGS_OFFSET 0x014 #define INIT_HCA_FLAGS_OFFSET 0x014
#define INIT_HCA_QPC_OFFSET 0x020 #define INIT_HCA_QPC_OFFSET 0x020
#define INIT_HCA_QPC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x10) #define INIT_HCA_QPC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x10)
@ -735,6 +737,9 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param)
*((u8 *) mailbox->buf + INIT_HCA_VERSION_OFFSET) = INIT_HCA_VERSION; *((u8 *) mailbox->buf + INIT_HCA_VERSION_OFFSET) = INIT_HCA_VERSION;
*((u8 *) mailbox->buf + INIT_HCA_CACHELINE_SZ_OFFSET) =
(ilog2(cache_line_size()) - 4) << 5;
#if defined(__LITTLE_ENDIAN) #if defined(__LITTLE_ENDIAN)
*(inbox + INIT_HCA_FLAGS_OFFSET / 4) &= ~cpu_to_be32(1 << 1); *(inbox + INIT_HCA_FLAGS_OFFSET / 4) &= ~cpu_to_be32(1 << 1);
#elif defined(__BIG_ENDIAN) #elif defined(__BIG_ENDIAN)