packet: account statistics only in tpacket_stats_u
[cascardo/linux.git] / net / packet / af_packet.c
index ba8309a..dd5cd49 100644 (file)
@@ -528,7 +528,7 @@ static void init_prb_bdqc(struct packet_sock *po,
        p1->hdrlen = po->tp_hdrlen;
        p1->version = po->tp_version;
        p1->last_kactive_blk_num = 0;
-       po->stats_u.stats3.tp_freeze_q_cnt = 0;
+       po->stats.stats3.tp_freeze_q_cnt = 0;
        if (req_u->req3.tp_retire_blk_tov)
                p1->retire_blk_tov = req_u->req3.tp_retire_blk_tov;
        else
@@ -696,7 +696,7 @@ static void prb_close_block(struct tpacket_kbdq_core *pkc1,
        struct tpacket3_hdr *last_pkt;
        struct tpacket_hdr_v1 *h1 = &pbd1->hdr.bh1;
 
-       if (po->stats.tp_drops)
+       if (po->stats.stats3.tp_drops)
                status |= TP_STATUS_LOSING;
 
        last_pkt = (struct tpacket3_hdr *)pkc1->prev;
@@ -801,7 +801,7 @@ static void prb_freeze_queue(struct tpacket_kbdq_core *pkc,
                                  struct packet_sock *po)
 {
        pkc->reset_pending_on_curr_blk = 1;
-       po->stats_u.stats3.tp_freeze_q_cnt++;
+       po->stats.stats3.tp_freeze_q_cnt++;
 }
 
 #define TOTAL_PKT_LEN_INCL_ALIGN(length) (ALIGN((length), V3_ALIGNMENT))
@@ -1687,7 +1687,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev,
        nf_reset(skb);
 
        spin_lock(&sk->sk_receive_queue.lock);
-       po->stats.tp_packets++;
+       po->stats.stats1.tp_packets++;
        skb->dropcount = atomic_read(&sk->sk_drops);
        __skb_queue_tail(&sk->sk_receive_queue, skb);
        spin_unlock(&sk->sk_receive_queue.lock);
@@ -1696,7 +1696,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev,
 
 drop_n_acct:
        spin_lock(&sk->sk_receive_queue.lock);
-       po->stats.tp_drops++;
+       po->stats.stats1.tp_drops++;
        atomic_inc(&sk->sk_drops);
        spin_unlock(&sk->sk_receive_queue.lock);
 
@@ -1796,10 +1796,10 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
         * Anyways, moving it for V1/V2 only as V3 doesn't need this
         * at packet level.
         */
-               if (po->stats.tp_drops)
+               if (po->stats.stats1.tp_drops)
                        status |= TP_STATUS_LOSING;
        }
-       po->stats.tp_packets++;
+       po->stats.stats1.tp_packets++;
        if (copy_skb) {
                status |= TP_STATUS_COPY;
                __skb_queue_tail(&sk->sk_receive_queue, copy_skb);
@@ -1898,7 +1898,7 @@ drop:
        return 0;
 
 ring_is_full:
-       po->stats.tp_drops++;
+       po->stats.stats1.tp_drops++;
        spin_unlock(&sk->sk_receive_queue.lock);
 
        sk->sk_data_ready(sk, 0);
@@ -3247,8 +3247,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
        struct sock *sk = sock->sk;
        struct packet_sock *po = pkt_sk(sk);
        void *data = &val;
-       struct tpacket_stats st;
-       union tpacket_stats_u st_u;
+       union tpacket_stats_u st;
 
        if (level != SOL_PACKET)
                return -ENOPROTOOPT;
@@ -3262,22 +3261,18 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
        switch (optname) {
        case PACKET_STATISTICS:
                spin_lock_bh(&sk->sk_receive_queue.lock);
+               memcpy(&st, &po->stats, sizeof(st));
+               memset(&po->stats, 0, sizeof(po->stats));
+               spin_unlock_bh(&sk->sk_receive_queue.lock);
+
                if (po->tp_version == TPACKET_V3) {
                        lv = sizeof(struct tpacket_stats_v3);
-                       memcpy(&st_u.stats3, &po->stats,
-                              sizeof(struct tpacket_stats));
-                       st_u.stats3.tp_freeze_q_cnt =
-                                       po->stats_u.stats3.tp_freeze_q_cnt;
-                       st_u.stats3.tp_packets += po->stats.tp_drops;
-                       data = &st_u.stats3;
+                       data = &st.stats3;
                } else {
                        lv = sizeof(struct tpacket_stats);
-                       st = po->stats;
-                       st.tp_packets += st.tp_drops;
-                       data = &st;
+                       data = &st.stats1;
                }
-               memset(&po->stats, 0, sizeof(st));
-               spin_unlock_bh(&sk->sk_receive_queue.lock);
+
                break;
        case PACKET_AUXDATA:
                val = po->auxdata;