Commit f64cd9de authored by Linus Torvalds's avatar Linus Torvalds

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

* 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband:
  IB/ipoib: Fix thinko in packet length checks
  IPoIB: Fix use-after-free in path_rec_completion()
  IB/ehca: Make scaling code work without CPU hotplug
  RDMA/cxgb3: Handle build_phys_page_list() failure in iwch_reregister_phys_mem()
  IB/ipath: Check return value of lookup_one_len
  IPoIB: Fix race in detaching from mcast group before attaching
  IPoIB/cm: Fix reaping of stale connections
parents 6b3964cd 77d8e1ef
...@@ -545,11 +545,14 @@ static int iwch_reregister_phys_mem(struct ib_mr *mr, ...@@ -545,11 +545,14 @@ static int iwch_reregister_phys_mem(struct ib_mr *mr,
php = to_iwch_pd(pd); php = to_iwch_pd(pd);
if (mr_rereg_mask & IB_MR_REREG_ACCESS) if (mr_rereg_mask & IB_MR_REREG_ACCESS)
mh.attr.perms = iwch_ib_to_tpt_access(acc); mh.attr.perms = iwch_ib_to_tpt_access(acc);
if (mr_rereg_mask & IB_MR_REREG_TRANS) if (mr_rereg_mask & IB_MR_REREG_TRANS) {
ret = build_phys_page_list(buffer_list, num_phys_buf, ret = build_phys_page_list(buffer_list, num_phys_buf,
iova_start, iova_start,
&total_size, &npages, &total_size, &npages,
&shift, &page_list); &shift, &page_list);
if (ret)
return ret;
}
ret = iwch_reregister_mem(rhp, php, &mh, shift, page_list, npages); ret = iwch_reregister_mem(rhp, php, &mh, shift, page_list, npages);
kfree(page_list); kfree(page_list);
......
...@@ -66,7 +66,9 @@ ...@@ -66,7 +66,9 @@
static void queue_comp_task(struct ehca_cq *__cq); static void queue_comp_task(struct ehca_cq *__cq);
static struct ehca_comp_pool* pool; static struct ehca_comp_pool* pool;
#ifdef CONFIG_HOTPLUG_CPU
static struct notifier_block comp_pool_callback_nb; static struct notifier_block comp_pool_callback_nb;
#endif
static inline void comp_event_callback(struct ehca_cq *cq) static inline void comp_event_callback(struct ehca_cq *cq)
{ {
...@@ -733,6 +735,7 @@ static void take_over_work(struct ehca_comp_pool *pool, ...@@ -733,6 +735,7 @@ static void take_over_work(struct ehca_comp_pool *pool,
} }
#ifdef CONFIG_HOTPLUG_CPU
static int comp_pool_callback(struct notifier_block *nfb, static int comp_pool_callback(struct notifier_block *nfb,
unsigned long action, unsigned long action,
void *hcpu) void *hcpu)
...@@ -775,6 +778,7 @@ static int comp_pool_callback(struct notifier_block *nfb, ...@@ -775,6 +778,7 @@ static int comp_pool_callback(struct notifier_block *nfb,
return NOTIFY_OK; return NOTIFY_OK;
} }
#endif
int ehca_create_comp_pool(void) int ehca_create_comp_pool(void)
{ {
...@@ -805,9 +809,11 @@ int ehca_create_comp_pool(void) ...@@ -805,9 +809,11 @@ int ehca_create_comp_pool(void)
} }
} }
#ifdef CONFIG_HOTPLUG_CPU
comp_pool_callback_nb.notifier_call = comp_pool_callback; comp_pool_callback_nb.notifier_call = comp_pool_callback;
comp_pool_callback_nb.priority =0; comp_pool_callback_nb.priority =0;
register_cpu_notifier(&comp_pool_callback_nb); register_cpu_notifier(&comp_pool_callback_nb);
#endif
printk(KERN_INFO "eHCA scaling code enabled\n"); printk(KERN_INFO "eHCA scaling code enabled\n");
...@@ -821,7 +827,9 @@ void ehca_destroy_comp_pool(void) ...@@ -821,7 +827,9 @@ void ehca_destroy_comp_pool(void)
if (!ehca_scaling_code) if (!ehca_scaling_code)
return; return;
#ifdef CONFIG_HOTPLUG_CPU
unregister_cpu_notifier(&comp_pool_callback_nb); unregister_cpu_notifier(&comp_pool_callback_nb);
#endif
for (i = 0; i < NR_CPUS; i++) { for (i = 0; i < NR_CPUS; i++) {
if (cpu_online(i)) if (cpu_online(i))
......
...@@ -451,12 +451,18 @@ bail: ...@@ -451,12 +451,18 @@ bail:
return ret; return ret;
} }
static void remove_file(struct dentry *parent, char *name) static int remove_file(struct dentry *parent, char *name)
{ {
struct dentry *tmp; struct dentry *tmp;
int ret;
tmp = lookup_one_len(name, parent, strlen(name)); tmp = lookup_one_len(name, parent, strlen(name));
if (IS_ERR(tmp)) {
ret = PTR_ERR(tmp);
goto bail;
}
spin_lock(&dcache_lock); spin_lock(&dcache_lock);
spin_lock(&tmp->d_lock); spin_lock(&tmp->d_lock);
if (!(d_unhashed(tmp) && tmp->d_inode)) { if (!(d_unhashed(tmp) && tmp->d_inode)) {
...@@ -469,6 +475,14 @@ static void remove_file(struct dentry *parent, char *name) ...@@ -469,6 +475,14 @@ static void remove_file(struct dentry *parent, char *name)
spin_unlock(&tmp->d_lock); spin_unlock(&tmp->d_lock);
spin_unlock(&dcache_lock); spin_unlock(&dcache_lock);
} }
ret = 0;
bail:
/*
* We don't expect clients to care about the return value, but
* it's there if they need it.
*/
return ret;
} }
static int remove_device_files(struct super_block *sb, static int remove_device_files(struct super_block *sb,
......
...@@ -452,7 +452,7 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ ...@@ -452,7 +452,7 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_
skb->len, tx->mtu); skb->len, tx->mtu);
++priv->stats.tx_dropped; ++priv->stats.tx_dropped;
++priv->stats.tx_errors; ++priv->stats.tx_errors;
ipoib_cm_skb_too_long(dev, skb, tx->mtu - INFINIBAND_ALEN); ipoib_cm_skb_too_long(dev, skb, tx->mtu - IPOIB_ENCAP_LEN);
return; return;
} }
...@@ -1095,7 +1095,7 @@ static void ipoib_cm_stale_task(struct work_struct *work) ...@@ -1095,7 +1095,7 @@ static void ipoib_cm_stale_task(struct work_struct *work)
/* List if sorted by LRU, start from tail, /* List if sorted by LRU, start from tail,
* stop when we see a recently used entry */ * stop when we see a recently used entry */
p = list_entry(priv->cm.passive_ids.prev, typeof(*p), list); p = list_entry(priv->cm.passive_ids.prev, typeof(*p), list);
if (time_after_eq(jiffies, p->jiffies + IPOIB_CM_RX_TIMEOUT)) if (time_before_eq(jiffies, p->jiffies + IPOIB_CM_RX_TIMEOUT))
break; break;
list_del_init(&p->list); list_del_init(&p->list);
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
......
...@@ -328,9 +328,9 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, ...@@ -328,9 +328,9 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,
struct ipoib_tx_buf *tx_req; struct ipoib_tx_buf *tx_req;
u64 addr; u64 addr;
if (unlikely(skb->len > priv->mcast_mtu + INFINIBAND_ALEN)) { if (unlikely(skb->len > priv->mcast_mtu + IPOIB_ENCAP_LEN)) {
ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n", ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n",
skb->len, priv->mcast_mtu + INFINIBAND_ALEN); skb->len, priv->mcast_mtu + IPOIB_ENCAP_LEN);
++priv->stats.tx_dropped; ++priv->stats.tx_dropped;
++priv->stats.tx_errors; ++priv->stats.tx_errors;
ipoib_cm_skb_too_long(dev, skb, priv->mcast_mtu); ipoib_cm_skb_too_long(dev, skb, priv->mcast_mtu);
......
...@@ -380,7 +380,7 @@ static void path_rec_completion(int status, ...@@ -380,7 +380,7 @@ static void path_rec_completion(int status,
struct net_device *dev = path->dev; struct net_device *dev = path->dev;
struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ipoib_ah *ah = NULL; struct ipoib_ah *ah = NULL;
struct ipoib_neigh *neigh; struct ipoib_neigh *neigh, *tn;
struct sk_buff_head skqueue; struct sk_buff_head skqueue;
struct sk_buff *skb; struct sk_buff *skb;
unsigned long flags; unsigned long flags;
...@@ -418,7 +418,7 @@ static void path_rec_completion(int status, ...@@ -418,7 +418,7 @@ static void path_rec_completion(int status,
while ((skb = __skb_dequeue(&path->queue))) while ((skb = __skb_dequeue(&path->queue)))
__skb_queue_tail(&skqueue, skb); __skb_queue_tail(&skqueue, skb);
list_for_each_entry(neigh, &path->neigh_list, list) { list_for_each_entry_safe(neigh, tn, &path->neigh_list, list) {
kref_get(&path->ah->ref); kref_get(&path->ah->ref);
neigh->ah = path->ah; neigh->ah = path->ah;
memcpy(&neigh->dgid.raw, &path->pathrec.dgid.raw, memcpy(&neigh->dgid.raw, &path->pathrec.dgid.raw,
......
...@@ -644,6 +644,9 @@ static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast) ...@@ -644,6 +644,9 @@ static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast)
struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_dev_priv *priv = netdev_priv(dev);
int ret = 0; int ret = 0;
if (test_and_clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags))
ib_sa_free_multicast(mcast->mc);
if (test_and_clear_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags)) { if (test_and_clear_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags)) {
ipoib_dbg_mcast(priv, "leaving MGID " IPOIB_GID_FMT "\n", ipoib_dbg_mcast(priv, "leaving MGID " IPOIB_GID_FMT "\n",
IPOIB_GID_ARG(mcast->mcmember.mgid)); IPOIB_GID_ARG(mcast->mcmember.mgid));
...@@ -655,9 +658,6 @@ static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast) ...@@ -655,9 +658,6 @@ static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast)
ipoib_warn(priv, "ipoib_mcast_detach failed (result = %d)\n", ret); ipoib_warn(priv, "ipoib_mcast_detach failed (result = %d)\n", ret);
} }
if (test_and_clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags))
ib_sa_free_multicast(mcast->mc);
return 0; return 0;
} }
......
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