aboutsummaryrefslogtreecommitdiffstats
path: root/net/packet/af_packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/packet/af_packet.c')
-rw-r--r--net/packet/af_packet.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 3f5caa3fbd06..4f4fa323171d 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1767,7 +1767,7 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
1767 1767
1768out: 1768out:
1769 if (err && rollover) { 1769 if (err && rollover) {
1770 kfree(rollover); 1770 kfree_rcu(rollover, rcu);
1771 po->rollover = NULL; 1771 po->rollover = NULL;
1772 } 1772 }
1773 mutex_unlock(&fanout_mutex); 1773 mutex_unlock(&fanout_mutex);
@@ -1794,8 +1794,10 @@ static struct packet_fanout *fanout_release(struct sock *sk)
1794 else 1794 else
1795 f = NULL; 1795 f = NULL;
1796 1796
1797 if (po->rollover) 1797 if (po->rollover) {
1798 kfree_rcu(po->rollover, rcu); 1798 kfree_rcu(po->rollover, rcu);
1799 po->rollover = NULL;
1800 }
1799 } 1801 }
1800 mutex_unlock(&fanout_mutex); 1802 mutex_unlock(&fanout_mutex);
1801 1803
@@ -3849,6 +3851,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
3849 void *data = &val; 3851 void *data = &val;
3850 union tpacket_stats_u st; 3852 union tpacket_stats_u st;
3851 struct tpacket_rollover_stats rstats; 3853 struct tpacket_rollover_stats rstats;
3854 struct packet_rollover *rollover;
3852 3855
3853 if (level != SOL_PACKET) 3856 if (level != SOL_PACKET)
3854 return -ENOPROTOOPT; 3857 return -ENOPROTOOPT;
@@ -3927,13 +3930,18 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
3927 0); 3930 0);
3928 break; 3931 break;
3929 case PACKET_ROLLOVER_STATS: 3932 case PACKET_ROLLOVER_STATS:
3930 if (!po->rollover) 3933 rcu_read_lock();
3934 rollover = rcu_dereference(po->rollover);
3935 if (rollover) {
3936 rstats.tp_all = atomic_long_read(&rollover->num);
3937 rstats.tp_huge = atomic_long_read(&rollover->num_huge);
3938 rstats.tp_failed = atomic_long_read(&rollover->num_failed);
3939 data = &rstats;
3940 lv = sizeof(rstats);
3941 }
3942 rcu_read_unlock();
3943 if (!rollover)
3931 return -EINVAL; 3944 return -EINVAL;
3932 rstats.tp_all = atomic_long_read(&po->rollover->num);
3933 rstats.tp_huge = atomic_long_read(&po->rollover->num_huge);
3934 rstats.tp_failed = atomic_long_read(&po->rollover->num_failed);
3935 data = &rstats;
3936 lv = sizeof(rstats);
3937 break; 3945 break;
3938 case PACKET_TX_HAS_OFF: 3946 case PACKET_TX_HAS_OFF:
3939 val = po->tp_tx_has_off; 3947 val = po->tp_tx_has_off;