IPoIB: Use checksum offload support if available
For HCAs that support checksum offload (ie that set IB_DEVICE_UD_IP_CSUM in the device capabilities flags), have IPoIB set NETIF_F_IP_CSUM and use the HCA to generate and verify IP checksums. Signed-off-by: Eli Cohen <eli@mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
Родитель
3371836383
Коммит
6046136c74
|
@ -87,6 +87,7 @@ enum {
|
||||||
IPOIB_MCAST_STARTED = 8,
|
IPOIB_MCAST_STARTED = 8,
|
||||||
IPOIB_FLAG_ADMIN_CM = 9,
|
IPOIB_FLAG_ADMIN_CM = 9,
|
||||||
IPOIB_FLAG_UMCAST = 10,
|
IPOIB_FLAG_UMCAST = 10,
|
||||||
|
IPOIB_FLAG_CSUM = 11,
|
||||||
|
|
||||||
IPOIB_MAX_BACKOFF_SECONDS = 16,
|
IPOIB_MAX_BACKOFF_SECONDS = 16,
|
||||||
|
|
||||||
|
|
|
@ -1383,6 +1383,10 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
|
||||||
set_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
|
set_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
|
||||||
ipoib_warn(priv, "enabling connected mode "
|
ipoib_warn(priv, "enabling connected mode "
|
||||||
"will cause multicast packet drops\n");
|
"will cause multicast packet drops\n");
|
||||||
|
|
||||||
|
dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_SG);
|
||||||
|
priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM;
|
||||||
|
|
||||||
ipoib_flush_paths(dev);
|
ipoib_flush_paths(dev);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -1391,6 +1395,10 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
|
||||||
clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
|
clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
|
||||||
dev->mtu = min(priv->mcast_mtu, dev->mtu);
|
dev->mtu = min(priv->mcast_mtu, dev->mtu);
|
||||||
ipoib_flush_paths(dev);
|
ipoib_flush_paths(dev);
|
||||||
|
|
||||||
|
if (test_bit(IPOIB_FLAG_CSUM, &priv->flags))
|
||||||
|
dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -231,6 +231,10 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
|
||||||
skb->dev = dev;
|
skb->dev = dev;
|
||||||
/* XXX get correct PACKET_ type here */
|
/* XXX get correct PACKET_ type here */
|
||||||
skb->pkt_type = PACKET_HOST;
|
skb->pkt_type = PACKET_HOST;
|
||||||
|
|
||||||
|
if (test_bit(IPOIB_FLAG_CSUM, &priv->flags) && likely(wc->csum_ok))
|
||||||
|
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||||
|
|
||||||
netif_receive_skb(skb);
|
netif_receive_skb(skb);
|
||||||
|
|
||||||
repost:
|
repost:
|
||||||
|
@ -442,6 +446,11 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (skb->ip_summed == CHECKSUM_PARTIAL)
|
||||||
|
priv->tx_wr.send_flags |= IB_SEND_IP_CSUM;
|
||||||
|
else
|
||||||
|
priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM;
|
||||||
|
|
||||||
if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1),
|
if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1),
|
||||||
address->ah, qpn,
|
address->ah, qpn,
|
||||||
tx_req->mapping, skb_headlen(skb),
|
tx_req->mapping, skb_headlen(skb),
|
||||||
|
|
|
@ -1105,6 +1105,7 @@ static struct net_device *ipoib_add_port(const char *format,
|
||||||
struct ib_device *hca, u8 port)
|
struct ib_device *hca, u8 port)
|
||||||
{
|
{
|
||||||
struct ipoib_dev_priv *priv;
|
struct ipoib_dev_priv *priv;
|
||||||
|
struct ib_device_attr *device_attr;
|
||||||
int result = -ENOMEM;
|
int result = -ENOMEM;
|
||||||
|
|
||||||
priv = ipoib_intf_alloc(format);
|
priv = ipoib_intf_alloc(format);
|
||||||
|
@ -1120,6 +1121,28 @@ static struct net_device *ipoib_add_port(const char *format,
|
||||||
goto device_init_failed;
|
goto device_init_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
device_attr = kmalloc(sizeof *device_attr, GFP_KERNEL);
|
||||||
|
if (!device_attr) {
|
||||||
|
printk(KERN_WARNING "%s: allocation of %zu bytes failed\n",
|
||||||
|
hca->name, sizeof *device_attr);
|
||||||
|
goto device_init_failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = ib_query_device(hca, device_attr);
|
||||||
|
if (result) {
|
||||||
|
printk(KERN_WARNING "%s: ib_query_device failed (ret = %d)\n",
|
||||||
|
hca->name, result);
|
||||||
|
kfree(device_attr);
|
||||||
|
goto device_init_failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device_attr->device_cap_flags & IB_DEVICE_UD_IP_CSUM) {
|
||||||
|
set_bit(IPOIB_FLAG_CSUM, &priv->flags);
|
||||||
|
priv->dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(device_attr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the full membership bit, so that we join the right
|
* Set the full membership bit, so that we join the right
|
||||||
* broadcast group, etc.
|
* broadcast group, etc.
|
||||||
|
@ -1137,7 +1160,6 @@ static struct net_device *ipoib_add_port(const char *format,
|
||||||
} else
|
} 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));
|
||||||
|
|
||||||
|
|
||||||
result = ipoib_dev_init(priv->dev, hca, port);
|
result = ipoib_dev_init(priv->dev, hca, port);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printk(KERN_WARNING "%s: failed to initialize port %d (ret = %d)\n",
|
printk(KERN_WARNING "%s: failed to initialize port %d (ret = %d)\n",
|
||||||
|
|
Загрузка…
Ссылка в новой задаче