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 bec01a3daf5b..2986941164b1 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1769,7 +1769,7 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
1769 1769
1770out: 1770out:
1771 if (err && rollover) { 1771 if (err && rollover) {
1772 kfree(rollover); 1772 kfree_rcu(rollover, rcu);
1773 po->rollover = NULL; 1773 po->rollover = NULL;
1774 } 1774 }
1775 mutex_unlock(&fanout_mutex); 1775 mutex_unlock(&fanout_mutex);
@@ -1796,8 +1796,10 @@ static struct packet_fanout *fanout_release(struct sock *sk)
1796 else 1796 else
1797 f = NULL; 1797 f = NULL;
1798 1798
1799 if (po->rollover) 1799 if (po->rollover) {
1800 kfree_rcu(po->rollover, rcu); 1800 kfree_rcu(po->rollover, rcu);
1801 po->rollover = NULL;
1802 }
1801 } 1803 }
1802 mutex_unlock(&fanout_mutex); 1804 mutex_unlock(&fanout_mutex);
1803 1805
@@ -3851,6 +3853,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
3851 void *data = &val; 3853 void *data = &val;
3852 union tpacket_stats_u st; 3854 union tpacket_stats_u st;
3853 struct tpacket_rollover_stats rstats; 3855 struct tpacket_rollover_stats rstats;
3856 struct packet_rollover *rollover;
3854 3857
3855 if (level != SOL_PACKET) 3858 if (level != SOL_PACKET)
3856 return -ENOPROTOOPT; 3859 return -ENOPROTOOPT;
@@ -3929,13 +3932,18 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
3929 0); 3932 0);
3930 break; 3933 break;
3931 case PACKET_ROLLOVER_STATS: 3934 case PACKET_ROLLOVER_STATS:
3932 if (!po->rollover) 3935 rcu_read_lock();
3936 rollover = rcu_dereference(po->rollover);
3937 if (rollover) {
3938 rstats.tp_all = atomic_long_read(&rollover->num);
3939 rstats.tp_huge = atomic_long_read(&rollover->num_huge);
3940 rstats.tp_failed = atomic_long_read(&rollover->num_failed);
3941 data = &rstats;
3942 lv = sizeof(rstats);
3943 }
3944 rcu_read_unlock();
3945 if (!rollover)
3933 return -EINVAL; 3946 return -EINVAL;
3934 rstats.tp_all = atomic_long_read(&po->rollover->num);
3935 rstats.tp_huge = atomic_long_read(&po->rollover->num_huge);
3936 rstats.tp_failed = atomic_long_read(&po->rollover->num_failed);
3937 data = &rstats;
3938 lv = sizeof(rstats);
3939 break; 3947 break;
3940 case PACKET_TX_HAS_OFF: 3948 case PACKET_TX_HAS_OFF:
3941 val = po->tp_tx_has_off; 3949 val = po->tp_tx_has_off;