Skip to content

Commit a9b6391

Browse files
wdebruijdavem330
authored andcommitted
packet: rollover statistics
Rollover indicates exceptional conditions. Export a counter to inform socket owners of this state. If no socket with sufficient room is found, rollover fails. Also count these events. Finally, also count when flows are rolled over early thanks to huge flow detection, to validate its correctness. Tested: Read counters in bench_rollover on all other tests in the patchset Signed-off-by: Willem de Bruijn <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 3b3a5b0 commit a9b6391

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

include/uapi/linux/if_packet.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ struct sockaddr_ll {
5454
#define PACKET_FANOUT 18
5555
#define PACKET_TX_HAS_OFF 19
5656
#define PACKET_QDISC_BYPASS 20
57+
#define PACKET_ROLLOVER_STATS 21
5758

5859
#define PACKET_FANOUT_HASH 0
5960
#define PACKET_FANOUT_LB 1
@@ -75,6 +76,12 @@ struct tpacket_stats_v3 {
7576
unsigned int tp_freeze_q_cnt;
7677
};
7778

79+
struct tpacket_rollover_stats {
80+
__aligned_u64 tp_all;
81+
__aligned_u64 tp_huge;
82+
__aligned_u64 tp_failed;
83+
};
84+
7885
union tpacket_stats_u {
7986
struct tpacket_stats stats1;
8087
struct tpacket_stats_v3 stats3;

net/packet/af_packet.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1395,7 +1395,7 @@ static unsigned int fanout_demux_rollover(struct packet_fanout *f,
13951395
unsigned int num)
13961396
{
13971397
struct packet_sock *po, *po_next;
1398-
unsigned int i, j, room;
1398+
unsigned int i, j, room = ROOM_NONE;
13991399

14001400
po = pkt_sk(f->arr[idx]);
14011401

@@ -1413,13 +1413,17 @@ static unsigned int fanout_demux_rollover(struct packet_fanout *f,
14131413
packet_rcv_has_room(po_next, skb) == ROOM_NORMAL) {
14141414
if (i != j)
14151415
po->rollover->sock = i;
1416+
atomic_long_inc(&po->rollover->num);
1417+
if (room == ROOM_LOW)
1418+
atomic_long_inc(&po->rollover->num_huge);
14161419
return i;
14171420
}
14181421

14191422
if (++i == num)
14201423
i = 0;
14211424
} while (i != j);
14221425

1426+
atomic_long_inc(&po->rollover->num_failed);
14231427
return idx;
14241428
}
14251429

@@ -1554,6 +1558,9 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
15541558
po->rollover = kzalloc(sizeof(*po->rollover), GFP_KERNEL);
15551559
if (!po->rollover)
15561560
return -ENOMEM;
1561+
atomic_long_set(&po->rollover->num, 0);
1562+
atomic_long_set(&po->rollover->num_huge, 0);
1563+
atomic_long_set(&po->rollover->num_failed, 0);
15571564
}
15581565

15591566
mutex_lock(&fanout_mutex);
@@ -3584,6 +3591,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
35843591
struct packet_sock *po = pkt_sk(sk);
35853592
void *data = &val;
35863593
union tpacket_stats_u st;
3594+
struct tpacket_rollover_stats rstats;
35873595

35883596
if (level != SOL_PACKET)
35893597
return -ENOPROTOOPT;
@@ -3659,6 +3667,15 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
36593667
((u32)po->fanout->flags << 24)) :
36603668
0);
36613669
break;
3670+
case PACKET_ROLLOVER_STATS:
3671+
if (!po->rollover)
3672+
return -EINVAL;
3673+
rstats.tp_all = atomic_long_read(&po->rollover->num);
3674+
rstats.tp_huge = atomic_long_read(&po->rollover->num_huge);
3675+
rstats.tp_failed = atomic_long_read(&po->rollover->num_failed);
3676+
data = &rstats;
3677+
lv = sizeof(rstats);
3678+
break;
36623679
case PACKET_TX_HAS_OFF:
36633680
val = po->tp_tx_has_off;
36643681
break;

net/packet/internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ struct packet_fanout {
8989

9090
struct packet_rollover {
9191
int sock;
92+
atomic_long_t num;
93+
atomic_long_t num_huge;
94+
atomic_long_t num_failed;
9295
#define ROLLOVER_HLEN (L1_CACHE_BYTES / sizeof(u32))
9396
u32 history[ROLLOVER_HLEN] ____cacheline_aligned;
9497
} ____cacheline_aligned_in_smp;

0 commit comments

Comments
 (0)