Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

IPoIB: Support modifying IPoIB CQ event moderation

This can be used to tune at run time the parameters controlling the
event (interrupt) generation rate and thus reduce the overhead
incurred by handling interrupts resulting in better throughput. Since
IPoIB uses a single CQ for both RX and TX, RX is chosen to dictate
configuration for both RX and TX.

Signed-off-by: Eli Cohen <eli@mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>

authored by

Eli Cohen and committed by
Roland Dreier
28d52b3c 2dd57162

+52
+6
drivers/infiniband/ulp/ipoib/ipoib.h
··· 242 242 int num_frags; 243 243 }; 244 244 245 + struct ipoib_ethtool_st { 246 + u16 coalesce_usecs; 247 + u16 max_coalesced_frames; 248 + }; 249 + 245 250 /* 246 251 * Device private locking: tx_lock protects members used in TX fast 247 252 * path (and we use LLTX so upper layers don't do extra locking). ··· 325 320 struct dentry *path_dentry; 326 321 #endif 327 322 int hca_caps; 323 + struct ipoib_ethtool_st ethtool; 328 324 }; 329 325 330 326 struct ipoib_ah {
+46
drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
··· 42 42 strncpy(drvinfo->driver, "ipoib", sizeof(drvinfo->driver) - 1); 43 43 } 44 44 45 + static int ipoib_get_coalesce(struct net_device *dev, 46 + struct ethtool_coalesce *coal) 47 + { 48 + struct ipoib_dev_priv *priv = netdev_priv(dev); 49 + 50 + coal->rx_coalesce_usecs = priv->ethtool.coalesce_usecs; 51 + coal->tx_coalesce_usecs = priv->ethtool.coalesce_usecs; 52 + coal->rx_max_coalesced_frames = priv->ethtool.max_coalesced_frames; 53 + coal->tx_max_coalesced_frames = priv->ethtool.max_coalesced_frames; 54 + 55 + return 0; 56 + } 57 + 58 + static int ipoib_set_coalesce(struct net_device *dev, 59 + struct ethtool_coalesce *coal) 60 + { 61 + struct ipoib_dev_priv *priv = netdev_priv(dev); 62 + int ret; 63 + 64 + /* 65 + * Since IPoIB uses a single CQ for both rx and tx, we assume 66 + * that rx params dictate the configuration. These values are 67 + * saved in the private data and returned when ipoib_get_coalesce() 68 + * is called. 69 + */ 70 + if (coal->rx_coalesce_usecs > 0xffff || 71 + coal->rx_max_coalesced_frames > 0xffff) 72 + return -EINVAL; 73 + 74 + ret = ib_modify_cq(priv->cq, coal->rx_max_coalesced_frames, 75 + coal->rx_coalesce_usecs); 76 + if (ret && ret != -ENOSYS) { 77 + ipoib_warn(priv, "failed modifying CQ (%d)\n", ret); 78 + return ret; 79 + } 80 + 81 + coal->tx_coalesce_usecs = coal->rx_coalesce_usecs; 82 + coal->tx_max_coalesced_frames = coal->rx_max_coalesced_frames; 83 + priv->ethtool.coalesce_usecs = coal->rx_coalesce_usecs; 84 + priv->ethtool.max_coalesced_frames = coal->rx_max_coalesced_frames; 85 + 86 + return 0; 87 + } 88 + 45 89 static const struct ethtool_ops ipoib_ethtool_ops = { 46 90 .get_drvinfo = ipoib_get_drvinfo, 47 91 .get_tso = ethtool_op_get_tso, 92 + .get_coalesce = ipoib_get_coalesce, 93 + .set_coalesce = ipoib_set_coalesce, 48 94 }; 49 95 50 96 void ipoib_set_ethtool_ops(struct net_device *dev)