Skip to content

Commit 868fdb0

Browse files
edumazetdavem330
authored andcommitted
mlx4: remove mlx4_en_low_latency_recv()
Busy polling can now be handled in generic NAPI poll infrastructure. This removes complexity and fast path overhead : mlx4 used two spin_lock()/spin_unlock() pair per napi->poll() call in mlx4_en_cq_lock_napi()/mlx4_en_cq_unlock_napi() Tested: Without busy polling : lpaa23:~# echo 0 >/proc/sys/net/core/busy_read lpaa24:~# echo 0 >/proc/sys/net/core/busy_read lpaa23:~# ./netperf -H lpaa24 -t TCP_RR MIGRATED TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to lpaa24.prod.google.com () port 0 AF_INET : first burst 0 Local /Remote Socket Size Request Resp. Elapsed Trans. Send Recv Size Size Time Rate bytes Bytes bytes bytes secs. per sec 16384 87380 1 1 10.00 47330.78 With busy polling : lpaa23:~# echo 70 >/proc/sys/net/core/busy_read lpaa24:~# echo 70 >/proc/sys/net/core/busy_read lpaa23:~# ./netperf -H lpaa24 -t TCP_RR MIGRATED TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to lpaa24.prod.google.com () port 0 AF_INET : first burst 0 Local /Remote Socket Size Request Resp. Elapsed Trans. Send Recv Size Size Time Rate bytes Bytes bytes bytes secs. per sec 16384 87380 1 1 10.00 97643.55 Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent b59768c commit 868fdb0

File tree

4 files changed

+2
-198
lines changed

4 files changed

+2
-198
lines changed

drivers/net/ethernet/mellanox/mlx4/en_ethtool.c

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -337,11 +337,7 @@ static int mlx4_en_get_sset_count(struct net_device *dev, int sset)
337337
case ETH_SS_STATS:
338338
return bitmap_iterator_count(&it) +
339339
(priv->tx_ring_num * 2) +
340-
#ifdef CONFIG_NET_RX_BUSY_POLL
341-
(priv->rx_ring_num * 5);
342-
#else
343340
(priv->rx_ring_num * 2);
344-
#endif
345341
case ETH_SS_TEST:
346342
return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.flags
347343
& MLX4_DEV_CAP_FLAG_UC_LOOPBACK) * 2;
@@ -408,11 +404,6 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
408404
for (i = 0; i < priv->rx_ring_num; i++) {
409405
data[index++] = priv->rx_ring[i]->packets;
410406
data[index++] = priv->rx_ring[i]->bytes;
411-
#ifdef CONFIG_NET_RX_BUSY_POLL
412-
data[index++] = priv->rx_ring[i]->yields;
413-
data[index++] = priv->rx_ring[i]->misses;
414-
data[index++] = priv->rx_ring[i]->cleaned;
415-
#endif
416407
}
417408
spin_unlock_bh(&priv->stats_lock);
418409

@@ -486,14 +477,6 @@ static void mlx4_en_get_strings(struct net_device *dev,
486477
"rx%d_packets", i);
487478
sprintf(data + (index++) * ETH_GSTRING_LEN,
488479
"rx%d_bytes", i);
489-
#ifdef CONFIG_NET_RX_BUSY_POLL
490-
sprintf(data + (index++) * ETH_GSTRING_LEN,
491-
"rx%d_napi_yield", i);
492-
sprintf(data + (index++) * ETH_GSTRING_LEN,
493-
"rx%d_misses", i);
494-
sprintf(data + (index++) * ETH_GSTRING_LEN,
495-
"rx%d_cleaned", i);
496-
#endif
497480
}
498481
break;
499482
case ETH_SS_PRIV_FLAGS:

drivers/net/ethernet/mellanox/mlx4/en_netdev.c

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -69,34 +69,6 @@ int mlx4_en_setup_tc(struct net_device *dev, u8 up)
6969
return 0;
7070
}
7171

72-
#ifdef CONFIG_NET_RX_BUSY_POLL
73-
/* must be called with local_bh_disable()d */
74-
static int mlx4_en_low_latency_recv(struct napi_struct *napi)
75-
{
76-
struct mlx4_en_cq *cq = container_of(napi, struct mlx4_en_cq, napi);
77-
struct net_device *dev = cq->dev;
78-
struct mlx4_en_priv *priv = netdev_priv(dev);
79-
struct mlx4_en_rx_ring *rx_ring = priv->rx_ring[cq->ring];
80-
int done;
81-
82-
if (!priv->port_up)
83-
return LL_FLUSH_FAILED;
84-
85-
if (!mlx4_en_cq_lock_poll(cq))
86-
return LL_FLUSH_BUSY;
87-
88-
done = mlx4_en_process_rx_cq(dev, cq, 4);
89-
if (likely(done))
90-
rx_ring->cleaned += done;
91-
else
92-
rx_ring->misses++;
93-
94-
mlx4_en_cq_unlock_poll(cq);
95-
96-
return done;
97-
}
98-
#endif /* CONFIG_NET_RX_BUSY_POLL */
99-
10072
#ifdef CONFIG_RFS_ACCEL
10173

10274
struct mlx4_en_filter {
@@ -1561,8 +1533,6 @@ int mlx4_en_start_port(struct net_device *dev)
15611533
for (i = 0; i < priv->rx_ring_num; i++) {
15621534
cq = priv->rx_cq[i];
15631535

1564-
mlx4_en_cq_init_lock(cq);
1565-
15661536
err = mlx4_en_init_affinity_hint(priv, i);
15671537
if (err) {
15681538
en_err(priv, "Failed preparing IRQ affinity hint\n");
@@ -1859,13 +1829,6 @@ void mlx4_en_stop_port(struct net_device *dev, int detach)
18591829
for (i = 0; i < priv->rx_ring_num; i++) {
18601830
struct mlx4_en_cq *cq = priv->rx_cq[i];
18611831

1862-
local_bh_disable();
1863-
while (!mlx4_en_cq_lock_napi(cq)) {
1864-
pr_info("CQ %d locked\n", i);
1865-
mdelay(1);
1866-
}
1867-
local_bh_enable();
1868-
18691832
napi_synchronize(&cq->napi);
18701833
mlx4_en_deactivate_rx_ring(priv, priv->rx_ring[i]);
18711834
mlx4_en_deactivate_cq(priv, cq);
@@ -2503,9 +2466,6 @@ static const struct net_device_ops mlx4_netdev_ops = {
25032466
.ndo_setup_tc = mlx4_en_setup_tc,
25042467
#ifdef CONFIG_RFS_ACCEL
25052468
.ndo_rx_flow_steer = mlx4_en_filter_rfs,
2506-
#endif
2507-
#ifdef CONFIG_NET_RX_BUSY_POLL
2508-
.ndo_busy_poll = mlx4_en_low_latency_recv,
25092469
#endif
25102470
.ndo_get_phys_port_id = mlx4_en_get_phys_port_id,
25112471
#ifdef CONFIG_MLX4_EN_VXLAN

drivers/net/ethernet/mellanox/mlx4/en_rx.c

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -873,10 +873,8 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
873873
* - TCP/IP (v4)
874874
* - without IP options
875875
* - not an IP fragment
876-
* - no LLS polling in progress
877876
*/
878-
if (!mlx4_en_cq_busy_polling(cq) &&
879-
(dev->features & NETIF_F_GRO)) {
877+
if (dev->features & NETIF_F_GRO) {
880878
struct sk_buff *gro_skb = napi_get_frags(&cq->napi);
881879
if (!gro_skb)
882880
goto next;
@@ -992,11 +990,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
992990

993991
skb_mark_napi_id(skb, &cq->napi);
994992

995-
if (!mlx4_en_cq_busy_polling(cq))
996-
napi_gro_receive(&cq->napi, skb);
997-
else
998-
netif_receive_skb(skb);
999-
993+
napi_gro_receive(&cq->napi, skb);
1000994
next:
1001995
for (nr = 0; nr < priv->num_frags; nr++)
1002996
mlx4_en_free_frag(priv, frags, nr);
@@ -1038,13 +1032,8 @@ int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget)
10381032
struct mlx4_en_priv *priv = netdev_priv(dev);
10391033
int done;
10401034

1041-
if (!mlx4_en_cq_lock_napi(cq))
1042-
return budget;
1043-
10441035
done = mlx4_en_process_rx_cq(dev, cq, budget);
10451036

1046-
mlx4_en_cq_unlock_napi(cq);
1047-
10481037
/* If we used up all the quota - we're probably not done yet... */
10491038
if (done == budget) {
10501039
const struct cpumask *aff;

drivers/net/ethernet/mellanox/mlx4/mlx4_en.h

Lines changed: 0 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -320,11 +320,6 @@ struct mlx4_en_rx_ring {
320320
void *rx_info;
321321
unsigned long bytes;
322322
unsigned long packets;
323-
#ifdef CONFIG_NET_RX_BUSY_POLL
324-
unsigned long yields;
325-
unsigned long misses;
326-
unsigned long cleaned;
327-
#endif
328323
unsigned long csum_ok;
329324
unsigned long csum_none;
330325
unsigned long csum_complete;
@@ -347,18 +342,6 @@ struct mlx4_en_cq {
347342
struct mlx4_cqe *buf;
348343
#define MLX4_EN_OPCODE_ERROR 0x1e
349344

350-
#ifdef CONFIG_NET_RX_BUSY_POLL
351-
unsigned int state;
352-
#define MLX4_EN_CQ_STATE_IDLE 0
353-
#define MLX4_EN_CQ_STATE_NAPI 1 /* NAPI owns this CQ */
354-
#define MLX4_EN_CQ_STATE_POLL 2 /* poll owns this CQ */
355-
#define MLX4_CQ_LOCKED (MLX4_EN_CQ_STATE_NAPI | MLX4_EN_CQ_STATE_POLL)
356-
#define MLX4_EN_CQ_STATE_NAPI_YIELD 4 /* NAPI yielded this CQ */
357-
#define MLX4_EN_CQ_STATE_POLL_YIELD 8 /* poll yielded this CQ */
358-
#define CQ_YIELD (MLX4_EN_CQ_STATE_NAPI_YIELD | MLX4_EN_CQ_STATE_POLL_YIELD)
359-
#define CQ_USER_PEND (MLX4_EN_CQ_STATE_POLL | MLX4_EN_CQ_STATE_POLL_YIELD)
360-
spinlock_t poll_lock; /* protects from LLS/napi conflicts */
361-
#endif /* CONFIG_NET_RX_BUSY_POLL */
362345
struct irq_desc *irq_desc;
363346
};
364347

@@ -622,117 +605,6 @@ static inline struct mlx4_cqe *mlx4_en_get_cqe(void *buf, int idx, int cqe_sz)
622605
return buf + idx * cqe_sz;
623606
}
624607

625-
#ifdef CONFIG_NET_RX_BUSY_POLL
626-
static inline void mlx4_en_cq_init_lock(struct mlx4_en_cq *cq)
627-
{
628-
spin_lock_init(&cq->poll_lock);
629-
cq->state = MLX4_EN_CQ_STATE_IDLE;
630-
}
631-
632-
/* called from the device poll rutine to get ownership of a cq */
633-
static inline bool mlx4_en_cq_lock_napi(struct mlx4_en_cq *cq)
634-
{
635-
int rc = true;
636-
spin_lock(&cq->poll_lock);
637-
if (cq->state & MLX4_CQ_LOCKED) {
638-
WARN_ON(cq->state & MLX4_EN_CQ_STATE_NAPI);
639-
cq->state |= MLX4_EN_CQ_STATE_NAPI_YIELD;
640-
rc = false;
641-
} else
642-
/* we don't care if someone yielded */
643-
cq->state = MLX4_EN_CQ_STATE_NAPI;
644-
spin_unlock(&cq->poll_lock);
645-
return rc;
646-
}
647-
648-
/* returns true is someone tried to get the cq while napi had it */
649-
static inline bool mlx4_en_cq_unlock_napi(struct mlx4_en_cq *cq)
650-
{
651-
int rc = false;
652-
spin_lock(&cq->poll_lock);
653-
WARN_ON(cq->state & (MLX4_EN_CQ_STATE_POLL |
654-
MLX4_EN_CQ_STATE_NAPI_YIELD));
655-
656-
if (cq->state & MLX4_EN_CQ_STATE_POLL_YIELD)
657-
rc = true;
658-
cq->state = MLX4_EN_CQ_STATE_IDLE;
659-
spin_unlock(&cq->poll_lock);
660-
return rc;
661-
}
662-
663-
/* called from mlx4_en_low_latency_recv(), BH are disabled */
664-
static inline bool mlx4_en_cq_lock_poll(struct mlx4_en_cq *cq)
665-
{
666-
int rc = true;
667-
668-
spin_lock(&cq->poll_lock);
669-
if ((cq->state & MLX4_CQ_LOCKED)) {
670-
struct net_device *dev = cq->dev;
671-
struct mlx4_en_priv *priv = netdev_priv(dev);
672-
struct mlx4_en_rx_ring *rx_ring = priv->rx_ring[cq->ring];
673-
674-
cq->state |= MLX4_EN_CQ_STATE_POLL_YIELD;
675-
rc = false;
676-
rx_ring->yields++;
677-
} else
678-
/* preserve yield marks */
679-
cq->state |= MLX4_EN_CQ_STATE_POLL;
680-
spin_unlock(&cq->poll_lock);
681-
return rc;
682-
}
683-
684-
/* returns true if someone tried to get the cq while it was locked */
685-
static inline bool mlx4_en_cq_unlock_poll(struct mlx4_en_cq *cq)
686-
{
687-
int rc = false;
688-
689-
spin_lock(&cq->poll_lock);
690-
WARN_ON(cq->state & (MLX4_EN_CQ_STATE_NAPI));
691-
692-
if (cq->state & MLX4_EN_CQ_STATE_POLL_YIELD)
693-
rc = true;
694-
cq->state = MLX4_EN_CQ_STATE_IDLE;
695-
spin_unlock(&cq->poll_lock);
696-
return rc;
697-
}
698-
699-
/* true if a socket is polling, even if it did not get the lock */
700-
static inline bool mlx4_en_cq_busy_polling(struct mlx4_en_cq *cq)
701-
{
702-
WARN_ON(!(cq->state & MLX4_CQ_LOCKED));
703-
return cq->state & CQ_USER_PEND;
704-
}
705-
#else
706-
static inline void mlx4_en_cq_init_lock(struct mlx4_en_cq *cq)
707-
{
708-
}
709-
710-
static inline bool mlx4_en_cq_lock_napi(struct mlx4_en_cq *cq)
711-
{
712-
return true;
713-
}
714-
715-
static inline bool mlx4_en_cq_unlock_napi(struct mlx4_en_cq *cq)
716-
{
717-
return false;
718-
}
719-
720-
static inline bool mlx4_en_cq_lock_poll(struct mlx4_en_cq *cq)
721-
{
722-
return false;
723-
}
724-
725-
static inline bool mlx4_en_cq_unlock_poll(struct mlx4_en_cq *cq)
726-
{
727-
return false;
728-
}
729-
730-
static inline bool mlx4_en_cq_busy_polling(struct mlx4_en_cq *cq)
731-
{
732-
return false;
733-
}
734-
#endif /* CONFIG_NET_RX_BUSY_POLL */
735-
736608
#define MLX4_EN_WOL_DO_MODIFY (1ULL << 63)
737609

738610
void mlx4_en_update_loopback_state(struct net_device *dev,

0 commit comments

Comments
 (0)