Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1602533 > unrolled thread
| Started by | Elena Reshetova <elena.reshetova@intel.com> |
|---|---|
| First post | 2017-03-16 16:30 +0100 |
| Last post | 2017-03-16 16:40 +0100 |
| Articles | 20 on this page of 53 — 9 participants |
Back to article view | Back to linux.kernel
[PATCH 00/17] net subsystem refcount conversions Elena Reshetova <elena.reshetova@intel.com> - 2017-03-16 16:30 +0100
[PATCH 02/17] net: convert neigh_params.refcnt from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-16 16:30 +0100
[PATCH 10/17] net: convert in_device.refcnt from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-16 16:40 +0100
[PATCH 12/17] net: convert unix_address.refcnt from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-16 16:40 +0100
[PATCH 14/17] net: convert inet_frag_queue.refcnt from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-16 16:40 +0100
[PATCH 01/17] net: convert neighbour.refcnt from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-16 16:40 +0100
[PATCH 11/17] net: convert netpoll_info.refcnt from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-16 16:40 +0100
[PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-16 16:40 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Eric Dumazet <eric.dumazet@gmail.com> - 2017-03-16 18:00 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Kees Cook <keescook@chromium.org> - 2017-03-16 18:40 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t David Miller <davem@davemloft.net> - 2017-03-16 20:20 +0100
RE: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t "Reshetova, Elena" <elena.reshetova@intel.com> - 2017-03-17 08:50 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Eric Dumazet <eric.dumazet@gmail.com> - 2017-03-17 17:20 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Herbert Xu <herbert@gondor.apana.org.au> - 2017-03-18 18:00 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t David Miller <davem@davemloft.net> - 2017-03-19 02:40 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Peter Zijlstra <peterz@infradead.org> - 2017-03-20 11:50 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Peter Zijlstra <peterz@infradead.org> - 2017-03-20 14:30 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Peter Zijlstra <peterz@infradead.org> - 2017-03-20 14:50 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Eric Dumazet <eric.dumazet@gmail.com> - 2017-03-20 16:00 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Eric Dumazet <eric.dumazet@gmail.com> - 2017-03-20 17:20 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Eric Dumazet <eric.dumazet@gmail.com> - 2017-03-20 17:40 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Eric Dumazet <eric.dumazet@gmail.com> - 2017-03-20 16:30 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Peter Zijlstra <peterz@infradead.org> - 2017-03-20 16:50 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Kees Cook <keescook@chromium.org> - 2017-03-21 21:50 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Eric Dumazet <eric.dumazet@gmail.com> - 2017-03-21 22:30 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t David Miller <davem@davemloft.net> - 2017-03-21 23:40 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Kees Cook <keescook@chromium.org> - 2017-03-22 01:00 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Eric Dumazet <eric.dumazet@gmail.com> - 2017-03-22 03:10 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Peter Zijlstra <peterz@infradead.org> - 2017-03-22 13:30 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Eric Dumazet <eric.dumazet@gmail.com> - 2017-03-22 14:30 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Peter Zijlstra <peterz@infradead.org> - 2017-03-22 15:40 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Eric Dumazet <eric.dumazet@gmail.com> - 2017-03-22 16:00 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Peter Zijlstra <peterz@infradead.org> - 2017-03-22 16:10 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Eric Dumazet <eric.dumazet@gmail.com> - 2017-03-22 16:30 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Peter Zijlstra <peterz@infradead.org> - 2017-03-22 18:00 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Kees Cook <keescook@chromium.org> - 2017-03-22 20:10 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Peter Zijlstra <peterz@infradead.org> - 2017-03-22 14:50 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Herbert Xu <herbert@gondor.apana.org.au> - 2017-03-20 15:50 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Herbert Xu <herbert@gondor.apana.org.au> - 2017-03-20 14:50 +0100
RE: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t David Laight <David.Laight@ACULAB.COM> - 2017-03-20 15:20 +0100
Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t Peter Zijlstra <peterz@infradead.org> - 2017-03-20 15:30 +0100
RE: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t David Laight <David.Laight@ACULAB.COM> - 2017-03-20 16:10 +0100
[PATCH 05/17] net: convert sk_buff_fclones.fclone_ref from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-16 16:40 +0100
[PATCH 15/17] net: convert net.passive from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-16 16:40 +0100
[PATCH 16/17] net: convert netlbl_lsm_cache.refcount from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-16 16:40 +0100
[PATCH 09/17] net: convert ip_mc_list.refcnt from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-16 16:40 +0100
[PATCH 04/17] net: convert sk_buff.users from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-16 16:40 +0100
[PATCH 08/17] net: convert sk_filter.refcnt from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-16 16:40 +0100
Re: [PATCH 08/17] net: convert sk_filter.refcnt from atomic_t to refcount_t Daniel Borkmann <daniel@iogearbox.net> - 2017-03-16 17:10 +0100
RE: [PATCH 08/17] net: convert sk_filter.refcnt from atomic_t to refcount_t "Reshetova, Elena" <elena.reshetova@intel.com> - 2017-03-17 09:20 +0100
[PATCH 17/17] net: convert packet_fanout.sk_ref from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-16 16:40 +0100
[PATCH 06/17] net: convert sock.sk_wmem_alloc from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-16 16:40 +0100
[PATCH 13/17] net: convert fib_rule.refcnt from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-03-16 16:40 +0100
Page 1 of 3 [1] 2 3 Next page →
| From | Elena Reshetova <elena.reshetova@intel.com> |
|---|---|
| Date | 2017-03-16 16:30 +0100 |
| Subject | [PATCH 00/17] net subsystem refcount conversions |
| Message-ID | <tlFvH-gv-7@gated-at.bofh.it> |
This series, for core network subsystem components, replaces atomic_t reference counters with the new refcount_t type and API (see include/linux/refcount.h). By doing this we prevent intentional or accidental underflows or overflows that can led to use-after-free vulnerabilities. These patches contain only generic net pieces. Other changes will be sent separately. The patches are fully independent and can be cherry-picked separately. Since we convert all kernel subsystems in the same fashion, resulting in about 300 patches, we have to group them for sending at least in some fashion to be manageable. Please excuse the long cc list. If there are no objections to the patches, please merge them via respective trees. Elena Reshetova (17): net: convert neighbour.refcnt from atomic_t to refcount_t net: convert neigh_params.refcnt from atomic_t to refcount_t net: convert nf_bridge_info.use from atomic_t to refcount_t net: convert sk_buff.users from atomic_t to refcount_t net: convert sk_buff_fclones.fclone_ref from atomic_t to refcount_t net: convert sock.sk_wmem_alloc from atomic_t to refcount_t net: convert sock.sk_refcnt from atomic_t to refcount_t net: convert sk_filter.refcnt from atomic_t to refcount_t net: convert ip_mc_list.refcnt from atomic_t to refcount_t net: convert in_device.refcnt from atomic_t to refcount_t net: convert netpoll_info.refcnt from atomic_t to refcount_t net: convert unix_address.refcnt from atomic_t to refcount_t net: convert fib_rule.refcnt from atomic_t to refcount_t net: convert inet_frag_queue.refcnt from atomic_t to refcount_t net: convert net.passive from atomic_t to refcount_t net: convert netlbl_lsm_cache.refcount from atomic_t to refcount_t net: convert packet_fanout.sk_ref from atomic_t to refcount_t crypto/algif_aead.c | 2 +- drivers/atm/fore200e.c | 12 +----------- drivers/atm/he.c | 2 +- drivers/atm/idt77252.c | 4 ++-- drivers/infiniband/hw/nes/nes_cm.c | 4 ++-- drivers/isdn/mISDN/socket.c | 2 +- drivers/net/rionet.c | 2 +- drivers/s390/net/ctcm_main.c | 26 ++++++++++++------------ drivers/s390/net/netiucv.c | 10 +++++----- drivers/s390/net/qeth_core_main.c | 4 ++-- drivers/scsi/cxgbi/libcxgbi.h | 2 +- include/linux/atmdev.h | 2 +- include/linux/filter.h | 3 ++- include/linux/igmp.h | 3 ++- include/linux/inetdevice.h | 11 ++++++----- include/linux/netpoll.h | 3 ++- include/linux/skbuff.h | 16 +++++++-------- include/net/af_unix.h | 3 ++- include/net/arp.h | 2 +- include/net/fib_rules.h | 7 ++++--- include/net/inet_frag.h | 4 ++-- include/net/inet_hashtables.h | 4 ++-- include/net/ndisc.h | 2 +- include/net/neighbour.h | 15 +++++++------- include/net/net_namespace.h | 3 ++- include/net/netfilter/br_netfilter.h | 2 +- include/net/netlabel.h | 8 ++++---- include/net/request_sock.h | 9 +++++---- include/net/sock.h | 25 ++++++++++++------------ net/atm/br2684.c | 2 +- net/atm/clip.c | 8 ++++---- net/atm/common.c | 10 +++++----- net/atm/lec.c | 4 ++-- net/atm/mpc.c | 4 ++-- net/atm/pppoatm.c | 2 +- net/atm/proc.c | 2 +- net/atm/raw.c | 2 +- net/atm/signaling.c | 2 +- net/bluetooth/af_bluetooth.c | 2 +- net/bluetooth/rfcomm/sock.c | 2 +- net/bridge/br_netfilter_hooks.c | 4 ++-- net/caif/caif_socket.c | 2 +- net/core/datagram.c | 10 +++++----- net/core/dev.c | 10 +++++----- net/core/fib_rules.c | 4 ++-- net/core/filter.c | 7 ++++--- net/core/neighbour.c | 22 ++++++++++----------- net/core/net-sysfs.c | 2 +- net/core/net_namespace.c | 4 ++-- net/core/netpoll.c | 10 +++++----- net/core/pktgen.c | 16 +++++++-------- net/core/rtnetlink.c | 2 +- net/core/skbuff.c | 38 ++++++++++++++++++------------------ net/core/sock.c | 30 ++++++++++++++-------------- net/dccp/ipv6.c | 2 +- net/decnet/dn_neigh.c | 2 +- net/ipv4/af_inet.c | 2 +- net/ipv4/cipso_ipv4.c | 4 ++-- net/ipv4/devinet.c | 2 +- net/ipv4/esp4.c | 2 +- net/ipv4/igmp.c | 10 +++++----- net/ipv4/inet_connection_sock.c | 2 +- net/ipv4/inet_fragment.c | 14 ++++++------- net/ipv4/inet_hashtables.c | 4 ++-- net/ipv4/inet_timewait_sock.c | 8 ++++---- net/ipv4/ip_fragment.c | 2 +- net/ipv4/ip_output.c | 6 +++--- net/ipv4/ping.c | 4 ++-- net/ipv4/raw.c | 2 +- net/ipv4/syncookies.c | 2 +- net/ipv4/tcp.c | 4 ++-- net/ipv4/tcp_fastopen.c | 2 +- net/ipv4/tcp_ipv4.c | 4 ++-- net/ipv4/tcp_offload.c | 2 +- net/ipv4/tcp_output.c | 13 ++++++------ net/ipv4/udp.c | 6 +++--- net/ipv4/udp_diag.c | 4 ++-- net/ipv6/calipso.c | 4 ++-- net/ipv6/datagram.c | 2 +- net/ipv6/esp6.c | 2 +- net/ipv6/inet6_hashtables.c | 4 ++-- net/ipv6/ip6_output.c | 4 ++-- net/ipv6/syncookies.c | 2 +- net/ipv6/tcp_ipv6.c | 6 +++--- net/ipv6/udp.c | 2 +- net/kcm/kcmproc.c | 2 +- net/key/af_key.c | 8 ++++---- net/l2tp/l2tp_debugfs.c | 3 +-- net/llc/llc_conn.c | 8 ++++---- net/llc/llc_sap.c | 2 +- net/netfilter/xt_TPROXY.c | 4 ++-- net/netlink/af_netlink.c | 14 ++++++------- net/packet/af_packet.c | 14 ++++++------- net/packet/internal.h | 4 +++- net/phonet/socket.c | 4 ++-- net/rds/tcp_send.c | 2 +- net/rxrpc/af_rxrpc.c | 6 +++--- net/rxrpc/skbuff.c | 12 ++++++------ net/sched/em_meta.c | 2 +- net/sched/sch_atm.c | 2 +- net/sctp/output.c | 2 +- net/sctp/outqueue.c | 2 +- net/sctp/proc.c | 2 +- net/sctp/socket.c | 6 +++--- net/tipc/socket.c | 2 +- net/unix/af_unix.c | 16 +++++++-------- 106 files changed, 320 insertions(+), 319 deletions(-) -- 2.7.4
[toc] | [next] | [standalone]
| From | Elena Reshetova <elena.reshetova@intel.com> |
|---|---|
| Date | 2017-03-16 16:30 +0100 |
| Subject | [PATCH 02/17] net: convert neigh_params.refcnt from atomic_t to refcount_t |
| Message-ID | <tlFvJ-gv-57@gated-at.bofh.it> |
| In reply to | #1602533 |
refcount_t type and corresponding API should be
used instead of atomic_t when the variable is used as
a reference counter. This allows to avoid accidental
refcounter overflows that might lead to use-after-free
situations.
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David Windsor <dwindsor@gmail.com>
---
include/net/neighbour.h | 6 +++---
net/core/neighbour.c | 8 ++++----
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index 9a66cfc9..d2eab49 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -77,7 +77,7 @@ struct neigh_parms {
void *sysctl_table;
int dead;
- atomic_t refcnt;
+ refcount_t refcnt;
struct rcu_head rcu_head;
int reachable_time;
@@ -394,12 +394,12 @@ void neigh_sysctl_unregister(struct neigh_parms *p);
static inline void __neigh_parms_put(struct neigh_parms *parms)
{
- atomic_dec(&parms->refcnt);
+ refcount_dec(&parms->refcnt);
}
static inline struct neigh_parms *neigh_parms_clone(struct neigh_parms *parms)
{
- atomic_inc(&parms->refcnt);
+ refcount_inc(&parms->refcnt);
return parms;
}
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 36f8008..9b38acd 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -673,7 +673,7 @@ static void neigh_parms_destroy(struct neigh_parms *parms);
static inline void neigh_parms_put(struct neigh_parms *parms)
{
- if (atomic_dec_and_test(&parms->refcnt))
+ if (refcount_dec_and_test(&parms->refcnt))
neigh_parms_destroy(parms);
}
@@ -1436,7 +1436,7 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
p = kmemdup(&tbl->parms, sizeof(*p), GFP_KERNEL);
if (p) {
p->tbl = tbl;
- atomic_set(&p->refcnt, 1);
+ refcount_set(&p->refcnt, 1);
p->reachable_time =
neigh_rand_reach_time(NEIGH_VAR(p, BASE_REACHABLE_TIME));
dev_hold(dev);
@@ -1499,7 +1499,7 @@ void neigh_table_init(int index, struct neigh_table *tbl)
INIT_LIST_HEAD(&tbl->parms_list);
list_add(&tbl->parms.list, &tbl->parms_list);
write_pnet(&tbl->parms.net, &init_net);
- atomic_set(&tbl->parms.refcnt, 1);
+ refcount_set(&tbl->parms.refcnt, 1);
tbl->parms.reachable_time =
neigh_rand_reach_time(NEIGH_VAR(&tbl->parms, BASE_REACHABLE_TIME));
@@ -1746,7 +1746,7 @@ static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms)
if ((parms->dev &&
nla_put_u32(skb, NDTPA_IFINDEX, parms->dev->ifindex)) ||
- nla_put_u32(skb, NDTPA_REFCNT, atomic_read(&parms->refcnt)) ||
+ nla_put_u32(skb, NDTPA_REFCNT, refcount_read(&parms->refcnt)) ||
nla_put_u32(skb, NDTPA_QUEUE_LENBYTES,
NEIGH_VAR(parms, QUEUE_LEN_BYTES)) ||
/* approximative value for deprecated QUEUE_LEN (in packets) */
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Elena Reshetova <elena.reshetova@intel.com> |
|---|---|
| Date | 2017-03-16 16:40 +0100 |
| Subject | [PATCH 10/17] net: convert in_device.refcnt from atomic_t to refcount_t |
| Message-ID | <tlFFo-lI-3@gated-at.bofh.it> |
| In reply to | #1602533 |
refcount_t type and corresponding API should be
used instead of atomic_t when the variable is used as
a reference counter. This allows to avoid accidental
refcounter overflows that might lead to use-after-free
situations.
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David Windsor <dwindsor@gmail.com>
---
include/linux/inetdevice.h | 11 ++++++-----
net/ipv4/devinet.c | 2 +-
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index ee971f3..5cd9671 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -11,6 +11,7 @@
#include <linux/timer.h>
#include <linux/sysctl.h>
#include <linux/rtnetlink.h>
+#include <linux/refcount.h>
struct ipv4_devconf {
void *sysctl;
@@ -22,7 +23,7 @@ struct ipv4_devconf {
struct in_device {
struct net_device *dev;
- atomic_t refcnt;
+ refcount_t refcnt;
int dead;
struct in_ifaddr *ifa_list; /* IP ifaddr chain */
@@ -212,7 +213,7 @@ static inline struct in_device *in_dev_get(const struct net_device *dev)
rcu_read_lock();
in_dev = __in_dev_get_rcu(dev);
if (in_dev)
- atomic_inc(&in_dev->refcnt);
+ refcount_inc(&in_dev->refcnt);
rcu_read_unlock();
return in_dev;
}
@@ -233,12 +234,12 @@ void in_dev_finish_destroy(struct in_device *idev);
static inline void in_dev_put(struct in_device *idev)
{
- if (atomic_dec_and_test(&idev->refcnt))
+ if (refcount_dec_and_test(&idev->refcnt))
in_dev_finish_destroy(idev);
}
-#define __in_dev_put(idev) atomic_dec(&(idev)->refcnt)
-#define in_dev_hold(idev) atomic_inc(&(idev)->refcnt)
+#define __in_dev_put(idev) refcount_dec(&(idev)->refcnt)
+#define in_dev_hold(idev) refcount_inc(&(idev)->refcnt)
#endif /* __KERNEL__ */
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index cebedd5..1527146 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -251,7 +251,7 @@ static struct in_device *inetdev_init(struct net_device *dev)
/* Reference in_dev->dev */
dev_hold(dev);
/* Account for reference dev->ip_ptr (below) */
- in_dev_hold(in_dev);
+ refcount_set(&in_dev->refcnt, 1);
err = devinet_sysctl_register(in_dev);
if (err) {
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Elena Reshetova <elena.reshetova@intel.com> |
|---|---|
| Date | 2017-03-16 16:40 +0100 |
| Subject | [PATCH 12/17] net: convert unix_address.refcnt from atomic_t to refcount_t |
| Message-ID | <tlFFo-lI-17@gated-at.bofh.it> |
| In reply to | #1602533 |
refcount_t type and corresponding API should be
used instead of atomic_t when the variable is used as
a reference counter. This allows to avoid accidental
refcounter overflows that might lead to use-after-free
situations.
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David Windsor <dwindsor@gmail.com>
---
include/net/af_unix.h | 3 ++-
net/unix/af_unix.c | 8 ++++----
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index fd60ecc..3a385e4 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -4,6 +4,7 @@
#include <linux/socket.h>
#include <linux/un.h>
#include <linux/mutex.h>
+#include <linux/refcount.h>
#include <net/sock.h>
void unix_inflight(struct user_struct *user, struct file *fp);
@@ -21,7 +22,7 @@ extern spinlock_t unix_table_lock;
extern struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE];
struct unix_address {
- atomic_t refcnt;
+ refcount_t refcnt;
int len;
unsigned int hash;
struct sockaddr_un name[0];
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index e9f8102..5e2a402 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -212,7 +212,7 @@ EXPORT_SYMBOL_GPL(unix_peer_get);
static inline void unix_release_addr(struct unix_address *addr)
{
- if (atomic_dec_and_test(&addr->refcnt))
+ if (refcount_dec_and_test(&addr->refcnt))
kfree(addr);
}
@@ -861,7 +861,7 @@ static int unix_autobind(struct socket *sock)
goto out;
addr->name->sun_family = AF_UNIX;
- atomic_set(&addr->refcnt, 1);
+ refcount_set(&addr->refcnt, 1);
retry:
addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short);
@@ -1036,7 +1036,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
memcpy(addr->name, sunaddr, addr_len);
addr->len = addr_len;
addr->hash = hash ^ sk->sk_type;
- atomic_set(&addr->refcnt, 1);
+ refcount_set(&addr->refcnt, 1);
if (sun_path[0]) {
addr->hash = UNIX_HASH_SIZE;
@@ -1327,7 +1327,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
/* copy address information from listening to new sock*/
if (otheru->addr) {
- atomic_inc(&otheru->addr->refcnt);
+ refcount_inc(&otheru->addr->refcnt);
newu->addr = otheru->addr;
}
if (otheru->path.dentry) {
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Elena Reshetova <elena.reshetova@intel.com> |
|---|---|
| Date | 2017-03-16 16:40 +0100 |
| Subject | [PATCH 14/17] net: convert inet_frag_queue.refcnt from atomic_t to refcount_t |
| Message-ID | <tlFFo-lI-9@gated-at.bofh.it> |
| In reply to | #1602533 |
refcount_t type and corresponding API should be
used instead of atomic_t when the variable is used as
a reference counter. This allows to avoid accidental
refcounter overflows that might lead to use-after-free
situations.
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David Windsor <dwindsor@gmail.com>
---
include/net/inet_frag.h | 4 ++--
net/ipv4/inet_fragment.c | 14 +++++++-------
net/ipv4/ip_fragment.c | 2 +-
3 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
index 5894730..5a334bf 100644
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -50,7 +50,7 @@ struct inet_frag_queue {
spinlock_t lock;
struct timer_list timer;
struct hlist_node list;
- atomic_t refcnt;
+ refcount_t refcnt;
struct sk_buff *fragments;
struct sk_buff *fragments_tail;
ktime_t stamp;
@@ -129,7 +129,7 @@ void inet_frag_maybe_warn_overflow(struct inet_frag_queue *q,
static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f)
{
- if (atomic_dec_and_test(&q->refcnt))
+ if (refcount_dec_and_test(&q->refcnt))
inet_frag_destroy(q, f);
}
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index b5e9317..96e95e8 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -276,11 +276,11 @@ static inline void fq_unlink(struct inet_frag_queue *fq, struct inet_frags *f)
void inet_frag_kill(struct inet_frag_queue *fq, struct inet_frags *f)
{
if (del_timer(&fq->timer))
- atomic_dec(&fq->refcnt);
+ refcount_dec(&fq->refcnt);
if (!(fq->flags & INET_FRAG_COMPLETE)) {
fq_unlink(fq, f);
- atomic_dec(&fq->refcnt);
+ refcount_dec(&fq->refcnt);
}
}
EXPORT_SYMBOL(inet_frag_kill);
@@ -329,7 +329,7 @@ static struct inet_frag_queue *inet_frag_intern(struct netns_frags *nf,
*/
hlist_for_each_entry(qp, &hb->chain, list) {
if (qp->net == nf && f->match(qp, arg)) {
- atomic_inc(&qp->refcnt);
+ refcount_inc(&qp->refcnt);
spin_unlock(&hb->chain_lock);
qp_in->flags |= INET_FRAG_COMPLETE;
inet_frag_put(qp_in, f);
@@ -339,9 +339,9 @@ static struct inet_frag_queue *inet_frag_intern(struct netns_frags *nf,
#endif
qp = qp_in;
if (!mod_timer(&qp->timer, jiffies + nf->timeout))
- atomic_inc(&qp->refcnt);
+ refcount_inc(&qp->refcnt);
- atomic_inc(&qp->refcnt);
+ refcount_inc(&qp->refcnt);
hlist_add_head(&qp->list, &hb->chain);
spin_unlock(&hb->chain_lock);
@@ -370,7 +370,7 @@ static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf,
setup_timer(&q->timer, f->frag_expire, (unsigned long)q);
spin_lock_init(&q->lock);
- atomic_set(&q->refcnt, 1);
+ refcount_set(&q->refcnt, 1);
return q;
}
@@ -405,7 +405,7 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
spin_lock(&hb->chain_lock);
hlist_for_each_entry(q, &hb->chain, list) {
if (q->net == nf && f->match(q, key)) {
- atomic_inc(&q->refcnt);
+ refcount_inc(&q->refcnt);
spin_unlock(&hb->chain_lock);
return q;
}
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index bbe7f72..4fed6f6 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -303,7 +303,7 @@ static int ip_frag_reinit(struct ipq *qp)
unsigned int sum_truesize = 0;
if (!mod_timer(&qp->q.timer, jiffies + qp->q.net->timeout)) {
- atomic_inc(&qp->q.refcnt);
+ refcount_inc(&qp->q.refcnt);
return -ETIMEDOUT;
}
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Elena Reshetova <elena.reshetova@intel.com> |
|---|---|
| Date | 2017-03-16 16:40 +0100 |
| Subject | [PATCH 01/17] net: convert neighbour.refcnt from atomic_t to refcount_t |
| Message-ID | <tlFFo-lI-13@gated-at.bofh.it> |
| In reply to | #1602533 |
refcount_t type and corresponding API should be
used instead of atomic_t when the variable is used as
a reference counter. This allows to avoid accidental
refcounter overflows that might lead to use-after-free
situations.
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David Windsor <dwindsor@gmail.com>
---
include/net/arp.h | 2 +-
include/net/ndisc.h | 2 +-
include/net/neighbour.h | 9 +++++----
net/atm/clip.c | 6 +++---
net/core/neighbour.c | 14 +++++++-------
net/decnet/dn_neigh.c | 2 +-
6 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/include/net/arp.h b/include/net/arp.h
index 65619a2..17d90e4 100644
--- a/include/net/arp.h
+++ b/include/net/arp.h
@@ -28,7 +28,7 @@ static inline struct neighbour *__ipv4_neigh_lookup(struct net_device *dev, u32
rcu_read_lock_bh();
n = __ipv4_neigh_lookup_noref(dev, key);
- if (n && !atomic_inc_not_zero(&n->refcnt))
+ if (n && !refcount_inc_not_zero(&n->refcnt))
n = NULL;
rcu_read_unlock_bh();
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index 8a02146..54062c1 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -384,7 +384,7 @@ static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, cons
rcu_read_lock_bh();
n = __ipv6_neigh_lookup_noref(dev, pkey);
- if (n && !atomic_inc_not_zero(&n->refcnt))
+ if (n && !refcount_inc_not_zero(&n->refcnt))
n = NULL;
rcu_read_unlock_bh();
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index 5ebf694..9a66cfc9 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -17,6 +17,7 @@
*/
#include <linux/atomic.h>
+#include <linux/refcount.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/rcupdate.h>
@@ -137,7 +138,7 @@ struct neighbour {
unsigned long confirmed;
unsigned long updated;
rwlock_t lock;
- atomic_t refcnt;
+ refcount_t refcnt;
struct sk_buff_head arp_queue;
unsigned int arp_queue_len_bytes;
struct timer_list timer;
@@ -408,18 +409,18 @@ static inline struct neigh_parms *neigh_parms_clone(struct neigh_parms *parms)
static inline void neigh_release(struct neighbour *neigh)
{
- if (atomic_dec_and_test(&neigh->refcnt))
+ if (refcount_dec_and_test(&neigh->refcnt))
neigh_destroy(neigh);
}
static inline struct neighbour * neigh_clone(struct neighbour *neigh)
{
if (neigh)
- atomic_inc(&neigh->refcnt);
+ refcount_inc(&neigh->refcnt);
return neigh;
}
-#define neigh_hold(n) atomic_inc(&(n)->refcnt)
+#define neigh_hold(n) refcount_inc(&(n)->refcnt)
static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
{
diff --git a/net/atm/clip.c b/net/atm/clip.c
index 53b4ac0..33e0940 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -137,11 +137,11 @@ static int neigh_check_cb(struct neighbour *n)
if (entry->vccs || time_before(jiffies, entry->expires))
return 0;
- if (atomic_read(&n->refcnt) > 1) {
+ if (refcount_read(&n->refcnt) > 1) {
struct sk_buff *skb;
pr_debug("destruction postponed with ref %d\n",
- atomic_read(&n->refcnt));
+ refcount_read(&n->refcnt));
while ((skb = skb_dequeue(&n->arp_queue)) != NULL)
dev_kfree_skb(skb);
@@ -767,7 +767,7 @@ static void atmarp_info(struct seq_file *seq, struct neighbour *n,
seq_printf(seq, "(resolving)\n");
else
seq_printf(seq, "(expired, ref %d)\n",
- atomic_read(&entry->neigh->refcnt));
+ refcount_read(&entry->neigh->refcnt));
} else if (!svc) {
seq_printf(seq, "%d.%d.%d\n",
clip_vcc->vcc->dev->number,
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index e7c12ca..36f8008 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -140,7 +140,7 @@ static int neigh_forced_gc(struct neigh_table *tbl)
* - it is not permanent
*/
write_lock(&n->lock);
- if (atomic_read(&n->refcnt) == 1 &&
+ if (refcount_read(&n->refcnt) == 1 &&
!(n->nud_state & NUD_PERMANENT)) {
rcu_assign_pointer(*np,
rcu_dereference_protected(n->next,
@@ -218,7 +218,7 @@ static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev)
neigh_del_timer(n);
n->dead = 1;
- if (atomic_read(&n->refcnt) != 1) {
+ if (refcount_read(&n->refcnt) != 1) {
/* The most unpleasant situation.
We must destroy neighbour entry,
but someone still uses it.
@@ -299,7 +299,7 @@ static struct neighbour *neigh_alloc(struct neigh_table *tbl, struct net_device
NEIGH_CACHE_STAT_INC(tbl, allocs);
n->tbl = tbl;
- atomic_set(&n->refcnt, 1);
+ refcount_set(&n->refcnt, 1);
n->dead = 1;
out:
return n;
@@ -408,7 +408,7 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
rcu_read_lock_bh();
n = __neigh_lookup_noref(tbl, pkey, dev);
if (n) {
- if (!atomic_inc_not_zero(&n->refcnt))
+ if (!refcount_inc_not_zero(&n->refcnt))
n = NULL;
NEIGH_CACHE_STAT_INC(tbl, hits);
}
@@ -437,7 +437,7 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net,
n = rcu_dereference_bh(n->next)) {
if (!memcmp(n->primary_key, pkey, key_len) &&
net_eq(dev_net(n->dev), net)) {
- if (!atomic_inc_not_zero(&n->refcnt))
+ if (!refcount_inc_not_zero(&n->refcnt))
n = NULL;
NEIGH_CACHE_STAT_INC(tbl, hits);
break;
@@ -785,7 +785,7 @@ static void neigh_periodic_work(struct work_struct *work)
if (time_before(n->used, n->confirmed))
n->used = n->confirmed;
- if (atomic_read(&n->refcnt) == 1 &&
+ if (refcount_read(&n->refcnt) == 1 &&
(state == NUD_FAILED ||
time_after(jiffies, n->used + NEIGH_VAR(n->parms, GC_STALETIME)))) {
*np = n->next;
@@ -2183,7 +2183,7 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *neigh,
ci.ndm_used = jiffies_to_clock_t(now - neigh->used);
ci.ndm_confirmed = jiffies_to_clock_t(now - neigh->confirmed);
ci.ndm_updated = jiffies_to_clock_t(now - neigh->updated);
- ci.ndm_refcnt = atomic_read(&neigh->refcnt) - 1;
+ ci.ndm_refcnt = refcount_read(&neigh->refcnt) - 1;
read_unlock_bh(&neigh->lock);
if (nla_put_u32(skb, NDA_PROBES, atomic_read(&neigh->probes)) ||
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
index 482730c..d8f7b6d 100644
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -559,7 +559,7 @@ static inline void dn_neigh_format_entry(struct seq_file *seq,
(dn->flags&DN_NDFLAG_R2) ? "2" : "-",
(dn->flags&DN_NDFLAG_P3) ? "3" : "-",
dn->n.nud_state,
- atomic_read(&dn->n.refcnt),
+ refcount_read(&dn->n.refcnt),
dn->blksize,
(dn->n.dev) ? dn->n.dev->name : "?");
read_unlock(&n->lock);
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Elena Reshetova <elena.reshetova@intel.com> |
|---|---|
| Date | 2017-03-16 16:40 +0100 |
| Subject | [PATCH 11/17] net: convert netpoll_info.refcnt from atomic_t to refcount_t |
| Message-ID | <tlFFp-lI-45@gated-at.bofh.it> |
| In reply to | #1602533 |
refcount_t type and corresponding API should be
used instead of atomic_t when the variable is used as
a reference counter. This allows to avoid accidental
refcounter overflows that might lead to use-after-free
situations.
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David Windsor <dwindsor@gmail.com>
---
include/linux/netpoll.h | 3 ++-
net/core/netpoll.c | 6 +++---
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h
index 1828900..27c0aaa 100644
--- a/include/linux/netpoll.h
+++ b/include/linux/netpoll.h
@@ -11,6 +11,7 @@
#include <linux/interrupt.h>
#include <linux/rcupdate.h>
#include <linux/list.h>
+#include <linux/refcount.h>
union inet_addr {
__u32 all[4];
@@ -34,7 +35,7 @@ struct netpoll {
};
struct netpoll_info {
- atomic_t refcnt;
+ refcount_t refcnt;
struct semaphore dev_lock;
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 891d88e..8b9083d 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -626,7 +626,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev)
skb_queue_head_init(&npinfo->txq);
INIT_DELAYED_WORK(&npinfo->tx_work, queue_process);
- atomic_set(&npinfo->refcnt, 1);
+ refcount_set(&npinfo->refcnt, 1);
ops = np->dev->netdev_ops;
if (ops->ndo_netpoll_setup) {
@@ -636,7 +636,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev)
}
} else {
npinfo = rtnl_dereference(ndev->npinfo);
- atomic_inc(&npinfo->refcnt);
+ refcount_inc(&npinfo->refcnt);
}
npinfo->netpoll = np;
@@ -815,7 +815,7 @@ void __netpoll_cleanup(struct netpoll *np)
synchronize_srcu(&netpoll_srcu);
- if (atomic_dec_and_test(&npinfo->refcnt)) {
+ if (refcount_dec_and_test(&npinfo->refcnt)) {
const struct net_device_ops *ops;
ops = np->dev->netdev_ops;
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Elena Reshetova <elena.reshetova@intel.com> |
|---|---|
| Date | 2017-03-16 16:40 +0100 |
| Subject | [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t |
| Message-ID | <tlFFo-lI-31@gated-at.bofh.it> |
| In reply to | #1602533 |
refcount_t type and corresponding API should be
used instead of atomic_t when the variable is used as
a reference counter. This allows to avoid accidental
refcounter overflows that might lead to use-after-free
situations.
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David Windsor <dwindsor@gmail.com>
---
crypto/algif_aead.c | 2 +-
include/net/inet_hashtables.h | 4 ++--
include/net/request_sock.h | 9 +++++----
include/net/sock.h | 17 +++++++++--------
net/atm/proc.c | 2 +-
net/bluetooth/af_bluetooth.c | 2 +-
net/bluetooth/rfcomm/sock.c | 2 +-
net/core/skbuff.c | 6 +++---
net/core/sock.c | 4 ++--
net/ipv4/inet_connection_sock.c | 2 +-
net/ipv4/inet_hashtables.c | 4 ++--
net/ipv4/inet_timewait_sock.c | 8 ++++----
net/ipv4/ping.c | 4 ++--
net/ipv4/raw.c | 2 +-
net/ipv4/syncookies.c | 2 +-
net/ipv4/tcp_fastopen.c | 2 +-
net/ipv4/tcp_ipv4.c | 4 ++--
net/ipv4/udp.c | 6 +++---
net/ipv4/udp_diag.c | 4 ++--
net/ipv6/datagram.c | 2 +-
net/ipv6/inet6_hashtables.c | 4 ++--
net/ipv6/tcp_ipv6.c | 4 ++--
net/ipv6/udp.c | 2 +-
net/key/af_key.c | 2 +-
net/l2tp/l2tp_debugfs.c | 3 +--
net/llc/llc_conn.c | 8 ++++----
net/llc/llc_sap.c | 2 +-
net/netfilter/xt_TPROXY.c | 4 ++--
net/netlink/af_netlink.c | 6 +++---
net/packet/af_packet.c | 2 +-
net/phonet/socket.c | 2 +-
net/rxrpc/af_rxrpc.c | 2 +-
net/sched/em_meta.c | 2 +-
net/tipc/socket.c | 2 +-
net/unix/af_unix.c | 2 +-
35 files changed, 68 insertions(+), 67 deletions(-)
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
index 5a80537..607380d 100644
--- a/crypto/algif_aead.c
+++ b/crypto/algif_aead.c
@@ -750,7 +750,7 @@ static void aead_sock_destruct(struct sock *sk)
unsigned int ivlen = crypto_aead_ivsize(
crypto_aead_reqtfm(&ctx->aead_req));
- WARN_ON(atomic_read(&sk->sk_refcnt) != 0);
+ WARN_ON(refcount_read(&sk->sk_refcnt) != 0);
aead_put_sgl(sk);
sock_kzfree_s(sk, ctx->iv, ivlen);
sock_kfree_s(sk, ctx, ctx->len);
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 1178931..b9e6e0e 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -32,7 +32,7 @@
#include <net/tcp_states.h>
#include <net/netns/hash.h>
-#include <linux/atomic.h>
+#include <linux/refcount.h>
#include <asm/byteorder.h>
/* This is for all connections with a full identity, no wildcards.
@@ -334,7 +334,7 @@ static inline struct sock *inet_lookup(struct net *net,
sk = __inet_lookup(net, hashinfo, skb, doff, saddr, sport, daddr,
dport, dif, &refcounted);
- if (sk && !refcounted && !atomic_inc_not_zero(&sk->sk_refcnt))
+ if (sk && !refcounted && !refcount_inc_not_zero(&sk->sk_refcnt))
sk = NULL;
return sk;
}
diff --git a/include/net/request_sock.h b/include/net/request_sock.h
index a12a5d2..e76e8c2 100644
--- a/include/net/request_sock.h
+++ b/include/net/request_sock.h
@@ -19,6 +19,7 @@
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/bug.h>
+#include <linux/refcount.h>
#include <net/sock.h>
@@ -89,7 +90,7 @@ reqsk_alloc(const struct request_sock_ops *ops, struct sock *sk_listener,
return NULL;
req->rsk_listener = NULL;
if (attach_listener) {
- if (unlikely(!atomic_inc_not_zero(&sk_listener->sk_refcnt))) {
+ if (unlikely(!refcount_inc_not_zero(&sk_listener->sk_refcnt))) {
kmem_cache_free(ops->slab, req);
return NULL;
}
@@ -100,7 +101,7 @@ reqsk_alloc(const struct request_sock_ops *ops, struct sock *sk_listener,
sk_node_init(&req_to_sk(req)->sk_node);
sk_tx_queue_clear(req_to_sk(req));
req->saved_syn = NULL;
- atomic_set(&req->rsk_refcnt, 0);
+ refcount_set(&req->rsk_refcnt, 0);
return req;
}
@@ -108,7 +109,7 @@ reqsk_alloc(const struct request_sock_ops *ops, struct sock *sk_listener,
static inline void reqsk_free(struct request_sock *req)
{
/* temporary debugging */
- WARN_ON_ONCE(atomic_read(&req->rsk_refcnt) != 0);
+ WARN_ON_ONCE(refcount_read(&req->rsk_refcnt) != 0);
req->rsk_ops->destructor(req);
if (req->rsk_listener)
@@ -119,7 +120,7 @@ static inline void reqsk_free(struct request_sock *req)
static inline void reqsk_put(struct request_sock *req)
{
- if (atomic_dec_and_test(&req->rsk_refcnt))
+ if (refcount_dec_and_test(&req->rsk_refcnt))
reqsk_free(req);
}
diff --git a/include/net/sock.h b/include/net/sock.h
index 24dcdba..c4f2b6c 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -66,6 +66,7 @@
#include <linux/poll.h>
#include <linux/atomic.h>
+#include <linux/refcount.h>
#include <net/dst.h>
#include <net/checksum.h>
#include <net/tcp_states.h>
@@ -219,7 +220,7 @@ struct sock_common {
u32 skc_tw_rcv_nxt; /* struct tcp_timewait_sock */
};
- atomic_t skc_refcnt;
+ refcount_t skc_refcnt;
/* private: */
int skc_dontcopy_end[0];
union {
@@ -602,7 +603,7 @@ static inline bool __sk_del_node_init(struct sock *sk)
static __always_inline void sock_hold(struct sock *sk)
{
- atomic_inc(&sk->sk_refcnt);
+ refcount_inc(&sk->sk_refcnt);
}
/* Ungrab socket in the context, which assumes that socket refcnt
@@ -610,7 +611,7 @@ static __always_inline void sock_hold(struct sock *sk)
*/
static __always_inline void __sock_put(struct sock *sk)
{
- atomic_dec(&sk->sk_refcnt);
+ refcount_dec(&sk->sk_refcnt);
}
static inline bool sk_del_node_init(struct sock *sk)
@@ -619,7 +620,7 @@ static inline bool sk_del_node_init(struct sock *sk)
if (rc) {
/* paranoid for a while -acme */
- WARN_ON(atomic_read(&sk->sk_refcnt) == 1);
+ WARN_ON(refcount_read(&sk->sk_refcnt) == 1);
__sock_put(sk);
}
return rc;
@@ -641,7 +642,7 @@ static inline bool sk_nulls_del_node_init_rcu(struct sock *sk)
if (rc) {
/* paranoid for a while -acme */
- WARN_ON(atomic_read(&sk->sk_refcnt) == 1);
+ WARN_ON(refcount_read(&sk->sk_refcnt) == 1);
__sock_put(sk);
}
return rc;
@@ -1130,9 +1131,9 @@ static inline void sk_refcnt_debug_dec(struct sock *sk)
static inline void sk_refcnt_debug_release(const struct sock *sk)
{
- if (atomic_read(&sk->sk_refcnt) != 1)
+ if (refcount_read(&sk->sk_refcnt) != 1)
printk(KERN_DEBUG "Destruction of the %s socket %p delayed, refcnt=%d\n",
- sk->sk_prot->name, sk, atomic_read(&sk->sk_refcnt));
+ sk->sk_prot->name, sk, refcount_read(&sk->sk_refcnt));
}
#else /* SOCK_REFCNT_DEBUG */
#define sk_refcnt_debug_inc(sk) do { } while (0)
@@ -1641,7 +1642,7 @@ void sock_init_data(struct socket *sock, struct sock *sk);
/* Ungrab socket and destroy it, if it was the last reference. */
static inline void sock_put(struct sock *sk)
{
- if (atomic_dec_and_test(&sk->sk_refcnt))
+ if (refcount_dec_and_test(&sk->sk_refcnt))
sk_free(sk);
}
/* Generic version of sock_put(), dealing with all sockets
diff --git a/net/atm/proc.c b/net/atm/proc.c
index bbb6461..27c9c01 100644
--- a/net/atm/proc.c
+++ b/net/atm/proc.c
@@ -211,7 +211,7 @@ static void vcc_info(struct seq_file *seq, struct atm_vcc *vcc)
vcc->flags, sk->sk_err,
sk_wmem_alloc_get(sk), sk->sk_sndbuf,
sk_rmem_alloc_get(sk), sk->sk_rcvbuf,
- atomic_read(&sk->sk_refcnt));
+ refcount_read(&sk->sk_refcnt));
}
static void svc_info(struct seq_file *seq, struct atm_vcc *vcc)
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 69e1f7d..dbc00c2 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -631,7 +631,7 @@ static int bt_seq_show(struct seq_file *seq, void *v)
seq_printf(seq,
"%pK %-6d %-6u %-6u %-6u %-6lu %-6lu",
sk,
- atomic_read(&sk->sk_refcnt),
+ refcount_read(&sk->sk_refcnt),
sk_rmem_alloc_get(sk),
sk_wmem_alloc_get(sk),
from_kuid(seq_user_ns(seq), sock_i_uid(sk)),
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index aa1a814..951be13 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -197,7 +197,7 @@ static void rfcomm_sock_kill(struct sock *sk)
if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
return;
- BT_DBG("sk %p state %d refcnt %d", sk, sk->sk_state, atomic_read(&sk->sk_refcnt));
+ BT_DBG("sk %p state %d refcnt %d", sk, sk->sk_state, refcount_read(&sk->sk_refcnt));
/* Kill poor orphan */
bt_sock_unlink(&rfcomm_sk_list, sk);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index e81a27f..7927fa0 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3763,7 +3763,7 @@ struct sk_buff *skb_clone_sk(struct sk_buff *skb)
struct sock *sk = skb->sk;
struct sk_buff *clone;
- if (!sk || !atomic_inc_not_zero(&sk->sk_refcnt))
+ if (!sk || !refcount_inc_not_zero(&sk->sk_refcnt))
return NULL;
clone = skb_clone(skb, GFP_ATOMIC);
@@ -3829,7 +3829,7 @@ void skb_complete_tx_timestamp(struct sk_buff *skb,
/* Take a reference to prevent skb_orphan() from freeing the socket,
* but only if the socket refcount is not zero.
*/
- if (likely(atomic_inc_not_zero(&sk->sk_refcnt))) {
+ if (likely(refcount_inc_not_zero(&sk->sk_refcnt))) {
*skb_hwtstamps(skb) = *hwtstamps;
__skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND);
sock_put(sk);
@@ -3905,7 +3905,7 @@ void skb_complete_wifi_ack(struct sk_buff *skb, bool acked)
/* Take a reference to prevent skb_orphan() from freeing the socket,
* but only if the socket refcount is not zero.
*/
- if (likely(atomic_inc_not_zero(&sk->sk_refcnt))) {
+ if (likely(refcount_inc_not_zero(&sk->sk_refcnt))) {
err = sock_queue_err_skb(sk, skb);
sock_put(sk);
}
diff --git a/net/core/sock.c b/net/core/sock.c
index e830ddc..e4c52af 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1559,7 +1559,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
* (Documentation/RCU/rculist_nulls.txt for details)
*/
smp_wmb();
- atomic_set(&newsk->sk_refcnt, 2);
+ refcount_set(&newsk->sk_refcnt, 2);
/*
* Increment the counter in the same struct proto as the master
@@ -2517,7 +2517,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
* (Documentation/RCU/rculist_nulls.txt for details)
*/
smp_wmb();
- atomic_set(&sk->sk_refcnt, 1);
+ refcount_set(&sk->sk_refcnt, 1);
atomic_set(&sk->sk_drops, 0);
}
EXPORT_SYMBOL(sock_init_data);
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index b4d5980..f01adaf 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -755,7 +755,7 @@ static void reqsk_queue_hash_req(struct request_sock *req,
* are committed to memory and refcnt initialized.
*/
smp_wmb();
- atomic_set(&req->rsk_refcnt, 2 + 1);
+ refcount_set(&req->rsk_refcnt, 2 + 1);
}
void inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req,
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index e9a59d2..a4be2c1 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -246,7 +246,7 @@ EXPORT_SYMBOL_GPL(__inet_lookup_listener);
/* All sockets share common refcount, but have different destructors */
void sock_gen_put(struct sock *sk)
{
- if (!atomic_dec_and_test(&sk->sk_refcnt))
+ if (!refcount_dec_and_test(&sk->sk_refcnt))
return;
if (sk->sk_state == TCP_TIME_WAIT)
@@ -287,7 +287,7 @@ struct sock *__inet_lookup_established(struct net *net,
continue;
if (likely(INET_MATCH(sk, net, acookie,
saddr, daddr, ports, dif))) {
- if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt)))
+ if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt)))
goto out;
if (unlikely(!INET_MATCH(sk, net, acookie,
saddr, daddr, ports, dif))) {
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index f8aff2c..5b03915 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -76,7 +76,7 @@ void inet_twsk_free(struct inet_timewait_sock *tw)
void inet_twsk_put(struct inet_timewait_sock *tw)
{
- if (atomic_dec_and_test(&tw->tw_refcnt))
+ if (refcount_dec_and_test(&tw->tw_refcnt))
inet_twsk_free(tw);
}
EXPORT_SYMBOL_GPL(inet_twsk_put);
@@ -131,7 +131,7 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
* We can use atomic_set() because prior spin_lock()/spin_unlock()
* committed into memory all tw fields.
*/
- atomic_set(&tw->tw_refcnt, 4);
+ refcount_set(&tw->tw_refcnt, 4);
inet_twsk_add_node_rcu(tw, &ehead->chain);
/* Step 3: Remove SK from hash chain */
@@ -195,7 +195,7 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk,
* to a non null value before everything is setup for this
* timewait socket.
*/
- atomic_set(&tw->tw_refcnt, 0);
+ refcount_set(&tw->tw_refcnt, 0);
__module_get(tw->tw_prot->owner);
}
@@ -278,7 +278,7 @@ void inet_twsk_purge(struct inet_hashinfo *hashinfo, int family)
atomic_read(&twsk_net(tw)->count))
continue;
- if (unlikely(!atomic_inc_not_zero(&tw->tw_refcnt)))
+ if (unlikely(!refcount_inc_not_zero(&tw->tw_refcnt)))
continue;
if (unlikely((tw->tw_family != family) ||
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 2af6244..c5434b9 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -289,7 +289,7 @@ void ping_close(struct sock *sk, long timeout)
{
pr_debug("ping_close(sk=%p,sk->num=%u)\n",
inet_sk(sk), inet_sk(sk)->inet_num);
- pr_debug("isk->refcnt = %d\n", sk->sk_refcnt.counter);
+ pr_debug("isk->refcnt = %d\n", refcount_read(&sk->sk_refcnt));
sk_common_release(sk);
}
@@ -1126,7 +1126,7 @@ static void ping_v4_format_sock(struct sock *sp, struct seq_file *f,
0, 0L, 0,
from_kuid_munged(seq_user_ns(f), sock_i_uid(sp)),
0, sock_i_ino(sp),
- atomic_read(&sp->sk_refcnt), sp,
+ refcount_read(&sp->sk_refcnt), sp,
atomic_read(&sp->sk_drops));
}
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 8119e1f..7ab99f0 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -1058,7 +1058,7 @@ static void raw_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)
0, 0L, 0,
from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
0, sock_i_ino(sp),
- atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));
+ refcount_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));
}
static int raw_seq_show(struct seq_file *seq, void *v)
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 496b97e..42d2426 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -212,7 +212,7 @@ struct sock *tcp_get_cookie_sock(struct sock *sk, struct sk_buff *skb,
child = icsk->icsk_af_ops->syn_recv_sock(sk, skb, req, dst,
NULL, &own_req);
if (child) {
- atomic_set(&req->rsk_refcnt, 1);
+ refcount_set(&req->rsk_refcnt, 1);
sock_rps_save_rxhash(child, skb);
inet_csk_reqsk_queue_add(sk, req, child);
} else {
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
index 8ea4e97..d527795 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -214,7 +214,7 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk,
inet_csk_reset_xmit_timer(child, ICSK_TIME_RETRANS,
TCP_TIMEOUT_INIT, TCP_RTO_MAX);
- atomic_set(&req->rsk_refcnt, 2);
+ refcount_set(&req->rsk_refcnt, 2);
/* Now finish processing the fastopen child socket. */
inet_csk(child)->icsk_af_ops->rebuild_header(child);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 69f2d20..bb5e4c4 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2269,7 +2269,7 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i)
from_kuid_munged(seq_user_ns(f), sock_i_uid(sk)),
icsk->icsk_probes_out,
sock_i_ino(sk),
- atomic_read(&sk->sk_refcnt), sk,
+ refcount_read(&sk->sk_refcnt), sk,
jiffies_to_clock_t(icsk->icsk_rto),
jiffies_to_clock_t(icsk->icsk_ack.ato),
(icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong,
@@ -2295,7 +2295,7 @@ static void get_timewait4_sock(const struct inet_timewait_sock *tw,
" %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %pK",
i, src, srcp, dest, destp, tw->tw_substate, 0, 0,
3, jiffies_delta_to_clock_t(delta), 0, 0, 0, 0,
- atomic_read(&tw->tw_refcnt), tw);
+ refcount_read(&tw->tw_refcnt), tw);
}
#define TMPSZ 150
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index ea6e4cf..c241d6df 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -577,7 +577,7 @@ struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
sk = __udp4_lib_lookup(net, saddr, sport, daddr, dport,
dif, &udp_table, NULL);
- if (sk && !atomic_inc_not_zero(&sk->sk_refcnt))
+ if (sk && !refcount_inc_not_zero(&sk->sk_refcnt))
sk = NULL;
return sk;
}
@@ -2082,7 +2082,7 @@ void udp_v4_early_demux(struct sk_buff *skb)
uh->source, iph->saddr, dif);
}
- if (!sk || !atomic_inc_not_zero_hint(&sk->sk_refcnt, 2))
+ if (!sk || !refcount_inc_not_zero(&sk->sk_refcnt))
return;
skb->sk = sk;
@@ -2530,7 +2530,7 @@ static void udp4_format_sock(struct sock *sp, struct seq_file *f,
0, 0L, 0,
from_kuid_munged(seq_user_ns(f), sock_i_uid(sp)),
0, sock_i_ino(sp),
- atomic_read(&sp->sk_refcnt), sp,
+ refcount_read(&sp->sk_refcnt), sp,
atomic_read(&sp->sk_drops));
}
diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c
index 9a89c10..4515836 100644
--- a/net/ipv4/udp_diag.c
+++ b/net/ipv4/udp_diag.c
@@ -55,7 +55,7 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb,
req->id.idiag_dport,
req->id.idiag_if, tbl, NULL);
#endif
- if (sk && !atomic_inc_not_zero(&sk->sk_refcnt))
+ if (sk && !refcount_inc_not_zero(&sk->sk_refcnt))
sk = NULL;
rcu_read_unlock();
err = -ENOENT;
@@ -206,7 +206,7 @@ static int __udp_diag_destroy(struct sk_buff *in_skb,
return -EINVAL;
}
- if (sk && !atomic_inc_not_zero(&sk->sk_refcnt))
+ if (sk && !refcount_inc_not_zero(&sk->sk_refcnt))
sk = NULL;
rcu_read_unlock();
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index eec27f8..a15c9a6 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -1043,6 +1043,6 @@ void ip6_dgram_sock_seq_show(struct seq_file *seq, struct sock *sp,
from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
0,
sock_i_ino(sp),
- atomic_read(&sp->sk_refcnt), sp,
+ refcount_read(&sp->sk_refcnt), sp,
atomic_read(&sp->sk_drops));
}
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index d090091..b13b8f9 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -75,7 +75,7 @@ struct sock *__inet6_lookup_established(struct net *net,
continue;
if (!INET6_MATCH(sk, net, saddr, daddr, ports, dif))
continue;
- if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt)))
+ if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt)))
goto out;
if (unlikely(!INET6_MATCH(sk, net, saddr, daddr, ports, dif))) {
@@ -172,7 +172,7 @@ struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo,
sk = __inet6_lookup(net, hashinfo, skb, doff, saddr, sport, daddr,
ntohs(dport), dif, &refcounted);
- if (sk && !refcounted && !atomic_inc_not_zero(&sk->sk_refcnt))
+ if (sk && !refcounted && !refcount_inc_not_zero(&sk->sk_refcnt))
sk = NULL;
return sk;
}
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 21bb2fc..1a55d49 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1796,7 +1796,7 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
icsk->icsk_probes_out,
sock_i_ino(sp),
- atomic_read(&sp->sk_refcnt), sp,
+ refcount_read(&sp->sk_refcnt), sp,
jiffies_to_clock_t(icsk->icsk_rto),
jiffies_to_clock_t(icsk->icsk_ack.ato),
(icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong,
@@ -1829,7 +1829,7 @@ static void get_timewait6_sock(struct seq_file *seq,
dest->s6_addr32[2], dest->s6_addr32[3], destp,
tw->tw_substate, 0, 0,
3, jiffies_delta_to_clock_t(delta), 0, 0, 0, 0,
- atomic_read(&tw->tw_refcnt), tw);
+ refcount_read(&tw->tw_refcnt), tw);
}
static int tcp6_seq_show(struct seq_file *seq, void *v)
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 4e4c401..deff3a6 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -324,7 +324,7 @@ struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be
sk = __udp6_lib_lookup(net, saddr, sport, daddr, dport,
dif, &udp_table, NULL);
- if (sk && !atomic_inc_not_zero(&sk->sk_refcnt))
+ if (sk && !refcount_inc_not_zero(&sk->sk_refcnt))
sk = NULL;
return sk;
}
diff --git a/net/key/af_key.c b/net/key/af_key.c
index ba00bd3..30ec662 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -3711,7 +3711,7 @@ static int pfkey_seq_show(struct seq_file *f, void *v)
else
seq_printf(f, "%pK %-6d %-6u %-6u %-6u %-6lu\n",
s,
- atomic_read(&s->sk_refcnt),
+ refcount_read(&s->sk_refcnt),
sk_rmem_alloc_get(s),
sk_wmem_alloc_get(s),
from_kuid_munged(seq_user_ns(f), sock_i_uid(s)),
diff --git a/net/l2tp/l2tp_debugfs.c b/net/l2tp/l2tp_debugfs.c
index 2d6760a..c87689d 100644
--- a/net/l2tp/l2tp_debugfs.c
+++ b/net/l2tp/l2tp_debugfs.c
@@ -144,9 +144,8 @@ static void l2tp_dfs_seq_tunnel_show(struct seq_file *m, void *v)
tunnel->encap == L2TP_ENCAPTYPE_IP ? "IP" :
"");
seq_printf(m, " %d sessions, refcnt %d/%d\n", session_count,
- tunnel->sock ? atomic_read(&tunnel->sock->sk_refcnt) : 0,
+ tunnel->sock ? refcount_read(&tunnel->sock->sk_refcnt) : 0,
atomic_read(&tunnel->ref_count));
-
seq_printf(m, " %08x rx %ld/%ld/%ld rx %ld/%ld/%ld\n",
tunnel->debug,
atomic_long_read(&tunnel->stats.tx_packets),
diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c
index 9b02c13..5e91b47 100644
--- a/net/llc/llc_conn.c
+++ b/net/llc/llc_conn.c
@@ -507,7 +507,7 @@ static struct sock *__llc_lookup_established(struct llc_sap *sap,
sk_nulls_for_each_rcu(rc, node, laddr_hb) {
if (llc_estab_match(sap, daddr, laddr, rc)) {
/* Extra checks required by SLAB_TYPESAFE_BY_RCU */
- if (unlikely(!atomic_inc_not_zero(&rc->sk_refcnt)))
+ if (unlikely(!refcount_inc_not_zero(&rc->sk_refcnt)))
goto again;
if (unlikely(llc_sk(rc)->sap != sap ||
!llc_estab_match(sap, daddr, laddr, rc))) {
@@ -566,7 +566,7 @@ static struct sock *__llc_lookup_listener(struct llc_sap *sap,
sk_nulls_for_each_rcu(rc, node, laddr_hb) {
if (llc_listener_match(sap, laddr, rc)) {
/* Extra checks required by SLAB_TYPESAFE_BY_RCU */
- if (unlikely(!atomic_inc_not_zero(&rc->sk_refcnt)))
+ if (unlikely(!refcount_inc_not_zero(&rc->sk_refcnt)))
goto again;
if (unlikely(llc_sk(rc)->sap != sap ||
!llc_listener_match(sap, laddr, rc))) {
@@ -973,9 +973,9 @@ void llc_sk_free(struct sock *sk)
skb_queue_purge(&sk->sk_write_queue);
skb_queue_purge(&llc->pdu_unack_q);
#ifdef LLC_REFCNT_DEBUG
- if (atomic_read(&sk->sk_refcnt) != 1) {
+ if (refcount_read(&sk->sk_refcnt) != 1) {
printk(KERN_DEBUG "Destruction of LLC sock %p delayed in %s, cnt=%d\n",
- sk, __func__, atomic_read(&sk->sk_refcnt));
+ sk, __func__, refcount_read(&sk->sk_refcnt));
printk(KERN_DEBUG "%d LLC sockets are still alive\n",
atomic_read(&llc_sock_nr));
} else {
diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c
index 63b6ab0..d90928f 100644
--- a/net/llc/llc_sap.c
+++ b/net/llc/llc_sap.c
@@ -329,7 +329,7 @@ static struct sock *llc_lookup_dgram(struct llc_sap *sap,
sk_nulls_for_each_rcu(rc, node, laddr_hb) {
if (llc_dgram_match(sap, laddr, rc)) {
/* Extra checks required by SLAB_TYPESAFE_BY_RCU */
- if (unlikely(!atomic_inc_not_zero(&rc->sk_refcnt)))
+ if (unlikely(!refcount_inc_not_zero(&rc->sk_refcnt)))
goto again;
if (unlikely(llc_sk(rc)->sap != sap ||
!llc_dgram_match(sap, laddr, rc))) {
diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c
index 80cb7ba..d51f1e8 100644
--- a/net/netfilter/xt_TPROXY.c
+++ b/net/netfilter/xt_TPROXY.c
@@ -127,7 +127,7 @@ nf_tproxy_get_sock_v4(struct net *net, struct sk_buff *skb, void *hp,
daddr, dport,
in->ifindex);
- if (sk && !atomic_inc_not_zero(&sk->sk_refcnt))
+ if (sk && !refcount_inc_not_zero(&sk->sk_refcnt))
sk = NULL;
/* NOTE: we return listeners even if bound to
* 0.0.0.0, those are filtered out in
@@ -197,7 +197,7 @@ nf_tproxy_get_sock_v6(struct net *net, struct sk_buff *skb, int thoff, void *hp,
daddr, ntohs(dport),
in->ifindex);
- if (sk && !atomic_inc_not_zero(&sk->sk_refcnt))
+ if (sk && !refcount_inc_not_zero(&sk->sk_refcnt))
sk = NULL;
/* NOTE: we return listeners even if bound to
* 0.0.0.0, those are filtered out in
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 9332b24..e3c9a6a 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -544,7 +544,7 @@ static void netlink_remove(struct sock *sk)
table = &nl_table[sk->sk_protocol];
if (!rhashtable_remove_fast(&table->hash, &nlk_sk(sk)->node,
netlink_rhashtable_params)) {
- WARN_ON(atomic_read(&sk->sk_refcnt) == 1);
+ WARN_ON(refcount_read(&sk->sk_refcnt) == 1);
__sock_put(sk);
}
@@ -657,7 +657,7 @@ static void deferred_put_nlk_sk(struct rcu_head *head)
struct netlink_sock *nlk = container_of(head, struct netlink_sock, rcu);
struct sock *sk = &nlk->sk;
- if (!atomic_dec_and_test(&sk->sk_refcnt))
+ if (!refcount_dec_and_test(&sk->sk_refcnt))
return;
if (nlk->cb_running && nlk->cb.done) {
@@ -2469,7 +2469,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v)
sk_rmem_alloc_get(s),
sk_wmem_alloc_get(s),
nlk->cb_running,
- atomic_read(&s->sk_refcnt),
+ refcount_read(&s->sk_refcnt),
atomic_read(&s->sk_drops),
sock_i_ino(s)
);
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 82eb052..ad5e5dc 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -4448,7 +4448,7 @@ static int packet_seq_show(struct seq_file *seq, void *v)
seq_printf(seq,
"%pK %-6d %-4d %04x %-5d %1d %-6u %-6u %-6lu\n",
s,
- atomic_read(&s->sk_refcnt),
+ refcount_read(&s->sk_refcnt),
s->sk_type,
ntohs(po->num),
po->ifindex,
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index 27b0b13..6b7aa30 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -614,7 +614,7 @@ static int pn_sock_seq_show(struct seq_file *seq, void *v)
sk_wmem_alloc_get(sk), sk_rmem_alloc_get(sk),
from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)),
sock_i_ino(sk),
- atomic_read(&sk->sk_refcnt), sk,
+ refcount_read(&sk->sk_refcnt), sk,
atomic_read(&sk->sk_drops));
}
seq_pad(seq, '\n');
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index b473ac2..e33e007 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -682,7 +682,7 @@ static int rxrpc_release_sock(struct sock *sk)
{
struct rxrpc_sock *rx = rxrpc_sk(sk);
- _enter("%p{%d,%d}", sk, sk->sk_state, atomic_read(&sk->sk_refcnt));
+ _enter("%p{%d,%d}", sk, sk->sk_state, refcount_read(&sk->sk_refcnt));
/* declare the socket closed for business */
sock_orphan(sk);
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index ae7e4f5..b1e7838 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -340,7 +340,7 @@ META_COLLECTOR(int_sk_refcnt)
*err = -1;
return;
}
- dst->value = atomic_read(&skb->sk->sk_refcnt);
+ dst->value = refcount_read(&skb->sk->sk_refcnt);
}
META_COLLECTOR(int_sk_rcvbuf)
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 43e4045..6991dbe 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -2307,7 +2307,7 @@ static void tipc_sk_remove(struct tipc_sock *tsk)
struct tipc_net *tn = net_generic(sock_net(sk), tipc_net_id);
if (!rhashtable_remove_fast(&tn->sk_rht, &tsk->node, tsk_rht_params)) {
- WARN_ON(atomic_read(&sk->sk_refcnt) == 1);
+ WARN_ON(refcount_read(&sk->sk_refcnt) == 1);
__sock_put(sk);
}
}
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index a74339e..e9f8102 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -2750,7 +2750,7 @@ static int unix_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, "%pK: %08X %08X %08X %04X %02X %5lu",
s,
- atomic_read(&s->sk_refcnt),
+ refcount_read(&s->sk_refcnt),
0,
s->sk_state == TCP_LISTEN ? __SO_ACCEPTCON : 0,
s->sk_type,
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Eric Dumazet <eric.dumazet@gmail.com> |
|---|---|
| Date | 2017-03-16 18:00 +0100 |
| Subject | Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t |
| Message-ID | <tlGUN-197-7@gated-at.bofh.it> |
| In reply to | #1602555 |
On Thu, 2017-03-16 at 17:28 +0200, Elena Reshetova wrote:
> refcount_t type and corresponding API should be
> used instead of atomic_t when the variable is used as
> a reference counter. This allows to avoid accidental
> refcounter overflows that might lead to use-after-free
> situations.
...
> static __always_inline void sock_hold(struct sock *sk)
> {
> - atomic_inc(&sk->sk_refcnt);
> + refcount_inc(&sk->sk_refcnt);
> }
>
While I certainly see the value of these refcount_t, we have a very
different behavior on these atomic_inc() which were doing a single
inlined LOCK RMW on x86.
We now call an external function performing a
atomic_read(), various ops/tests, then atomic_cmpxchg_relaxed(), in a
loop, loosing the nice ability for x86 of preventing live locks.
Looks a lot of bloat, just to be able to chase hypothetical bugs in the
kernel.
I would love to have a way to enable extra debugging when I want a debug
kernel, like LOCKDEP or KASAN.
By adding all this bloat, we assert linux kernel is terminally buggy and
every atomic_inc() we did was suspicious, and need to be always
instrumented/validated.
[toc] | [prev] | [next] | [standalone]
| From | Kees Cook <keescook@chromium.org> |
|---|---|
| Date | 2017-03-16 18:40 +0100 |
| Subject | Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t |
| Message-ID | <tlHxv-1ET-15@gated-at.bofh.it> |
| In reply to | #1602660 |
On Thu, Mar 16, 2017 at 10:58 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Thu, 2017-03-16 at 17:28 +0200, Elena Reshetova wrote:
>> refcount_t type and corresponding API should be
>> used instead of atomic_t when the variable is used as
>> a reference counter. This allows to avoid accidental
>> refcounter overflows that might lead to use-after-free
>> situations.
>
>
> ...
>
>> static __always_inline void sock_hold(struct sock *sk)
>> {
>> - atomic_inc(&sk->sk_refcnt);
>> + refcount_inc(&sk->sk_refcnt);
>> }
>>
>
> While I certainly see the value of these refcount_t, we have a very
> different behavior on these atomic_inc() which were doing a single
> inlined LOCK RMW on x86.
I think we can certainly investigate arch-specific ways to improve the
performance, but the consensus seemed to be that getting the
infrastructure in and doing the migration was the first set of steps.
> We now call an external function performing a
> atomic_read(), various ops/tests, then atomic_cmpxchg_relaxed(), in a
> loop, loosing the nice ability for x86 of preventing live locks.
>
> Looks a lot of bloat, just to be able to chase hypothetical bugs in the
> kernel.
>
> I would love to have a way to enable extra debugging when I want a debug
> kernel, like LOCKDEP or KASAN.
>
> By adding all this bloat, we assert linux kernel is terminally buggy and
> every atomic_inc() we did was suspicious, and need to be always
> instrumented/validated.
This IS the assertion, unfortunately. With average 5 year lifetimes on
security flaws[1], and many of the last couple years' public exploits
being refcount flaws[2], this is something we have to get done. We
need the default kernel to be much more self-protective, and this is
one of many places to make it happen.
I am, of course, biased, but I think the evidence of actual
refcounting attacks outweighs the theoretical performance cost of
these changes. If there is a realistic workflow that shows actual
problems, let's examine it and find a solution for that as a separate
part of this work without blocking this migration.
-Kees
[1] https://outflux.net/blog/archives/2016/10/18/security-bug-lifetime/
[2] http://kernsec.org/wiki/index.php/Bug_Classes/Integer_overflow
--
Kees Cook
Pixel Security
[toc] | [prev] | [next] | [standalone]
| From | David Miller <davem@davemloft.net> |
|---|---|
| Date | 2017-03-16 20:20 +0100 |
| Subject | Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t |
| Message-ID | <tlJ6h-2QJ-1@gated-at.bofh.it> |
| In reply to | #1602700 |
From: Kees Cook <keescook@chromium.org> Date: Thu, 16 Mar 2017 11:38:25 -0600 > I am, of course, biased, but I think the evidence of actual > refcounting attacks outweighs the theoretical performance cost of > these changes. This is not theoretical at all. We count the nanoseconds that every packet takes to get processed and you are adding quite a bit. I understand your point of view, but this is knowingly going to add performance regressions to the networking code.
[toc] | [prev] | [next] | [standalone]
| From | "Reshetova, Elena" <elena.reshetova@intel.com> |
|---|---|
| Date | 2017-03-17 08:50 +0100 |
| Subject | RE: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t |
| Message-ID | <tlUO5-2W2-11@gated-at.bofh.it> |
| In reply to | #1602786 |
> From: Kees Cook <keescook@chromium.org> > Date: Thu, 16 Mar 2017 11:38:25 -0600 > > > I am, of course, biased, but I think the evidence of actual > > refcounting attacks outweighs the theoretical performance cost of > > these changes. > > This is not theoretical at all. > > We count the nanoseconds that every packet takes to get processed and > you are adding quite a bit. > > I understand your point of view, but this is knowingly going to add > performance regressions to the networking code. Should we then first measure the actual numbers to understand what we are talking here about? I would be glad to do it if you suggest what is the correct way to do measurements here to actually reflect the real life use cases. Best Regards, Elena.
[toc] | [prev] | [next] | [standalone]
| From | Eric Dumazet <eric.dumazet@gmail.com> |
|---|---|
| Date | 2017-03-17 17:20 +0100 |
| Subject | Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t |
| Message-ID | <tm2LE-KO-21@gated-at.bofh.it> |
| In reply to | #1603093 |
On Fri, 2017-03-17 at 07:42 +0000, Reshetova, Elena wrote: > Should we then first measure the actual numbers to understand what we > are talking here about? > I would be glad to do it if you suggest what is the correct way to do > measurements here to actually reflect the real life use cases. How have these patches been tested in real life exactly ? Can you quantify number of added cycles per TCP packet, where I expect we have maybe 20 atomic operations in all layers ... (sk refcnt, skb->users, page refcounts, sk->sk_wmem_alloc, sk->sk_rmem_alloc, qdisc ...) Once we 'protect' all of them, cost will be quite high. This translates to more fossil fuel being burnt. one atomic_inc() used to be a single x86 instruction. Rough estimate of refcount_inc() : 0000000000000140 <refcount_inc>: 140: 55 push %rbp 141: 48 89 e5 mov %rsp,%rbp 144: e8 00 00 00 00 callq refcount_inc_not_zero 149: 84 c0 test %al,%al 14b: 74 02 je 14f <refcount_inc+0xf> 14d: 5d pop %rbp 14e: c3 retq 00000000000000e0 <refcount_inc_not_zero>: e0: 8b 17 mov (%rdi),%edx e2: eb 10 jmp f4 <refcount_inc_not_zero+0x14> e4: 85 c9 test %ecx,%ecx e6: 74 1b je 103 <refcount_inc_not_zero+0x23> e8: 89 d0 mov %edx,%eax ea: f0 0f b1 0f lock cmpxchg %ecx,(%rdi) ee: 39 d0 cmp %edx,%eax f0: 74 0c je fe <refcount_inc_not_zero+0x1e> f2: 89 c2 mov %eax,%edx f4: 85 d2 test %edx,%edx f6: 8d 4a 01 lea 0x1(%rdx),%ecx f9: 75 e9 jne e4 <refcount_inc_not_zero+0x4> fb: 31 c0 xor %eax,%eax fd: c3 retq fe: 83 f9 ff cmp $0xffffffff,%ecx 101: 74 06 je 109 <refcount_inc_not_zero+0x29> 103: b8 01 00 00 00 mov $0x1,%eax 108: c3 retq This is simply bloat for most cases. Again, I believe this infrastructure makes sense for debugging kernels. If some vendors are willing to run fully enabled debug kernels, that is their choice. Probably many devices wont show any difference. Have we forced KASAN being enabled in linux kernel, just because it found ~400 bugs so far ? I believe refcount_t infra is not mature enough to be widely used right now. Maybe in few months when we have more flexibility, like existing debugging facilities (CONFIG_DEBUG_PAGEALLOC, CONFIG_DEBUG_PAGE_REF, LOCKDEP, KMEMLEAK, KASAN, ...)
[toc] | [prev] | [next] | [standalone]
| From | Herbert Xu <herbert@gondor.apana.org.au> |
|---|---|
| Date | 2017-03-18 18:00 +0100 |
| Subject | Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t |
| Message-ID | <tmpRT-JT-11@gated-at.bofh.it> |
| In reply to | #1603437 |
Eric Dumazet <eric.dumazet@gmail.com> wrote: > On Fri, 2017-03-17 at 07:42 +0000, Reshetova, Elena wrote: > >> Should we then first measure the actual numbers to understand what we >> are talking here about? >> I would be glad to do it if you suggest what is the correct way to do >> measurements here to actually reflect the real life use cases. > > How have these patches been tested in real life exactly ? > > Can you quantify number of added cycles per TCP packet, where I expect > we have maybe 20 atomic operations in all layers ... I completely agree. I think this thing needs to default to the existing atomic_t behaviour. Thanks, -- Email: Herbert Xu <herbert@gondor.apana.org.au> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
[toc] | [prev] | [next] | [standalone]
| From | David Miller <davem@davemloft.net> |
|---|---|
| Date | 2017-03-19 02:40 +0100 |
| Subject | Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t |
| Message-ID | <tmxZ7-6EK-5@gated-at.bofh.it> |
| In reply to | #1603814 |
From: Herbert Xu <herbert@gondor.apana.org.au> Date: Sun, 19 Mar 2017 00:47:59 +0800 > Eric Dumazet <eric.dumazet@gmail.com> wrote: >> On Fri, 2017-03-17 at 07:42 +0000, Reshetova, Elena wrote: >> >>> Should we then first measure the actual numbers to understand what we >>> are talking here about? >>> I would be glad to do it if you suggest what is the correct way to do >>> measurements here to actually reflect the real life use cases. >> >> How have these patches been tested in real life exactly ? >> >> Can you quantify number of added cycles per TCP packet, where I expect >> we have maybe 20 atomic operations in all layers ... > > I completely agree. I think this thing needs to default to the > existing atomic_t behaviour. I totally agree as well, the refcount_t facility as-is is unacceptable for networking.
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2017-03-20 11:50 +0100 |
| Subject | Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t |
| Message-ID | <tn32W-3u2-9@gated-at.bofh.it> |
| In reply to | #1603878 |
On Sat, Mar 18, 2017 at 06:21:21PM -0700, David Miller wrote: > From: Herbert Xu <herbert@gondor.apana.org.au> > Date: Sun, 19 Mar 2017 00:47:59 +0800 > > > Eric Dumazet <eric.dumazet@gmail.com> wrote: > >> On Fri, 2017-03-17 at 07:42 +0000, Reshetova, Elena wrote: > >> > >>> Should we then first measure the actual numbers to understand what we > >>> are talking here about? > >>> I would be glad to do it if you suggest what is the correct way to do > >>> measurements here to actually reflect the real life use cases. > >> > >> How have these patches been tested in real life exactly ? > >> > >> Can you quantify number of added cycles per TCP packet, where I expect > >> we have maybe 20 atomic operations in all layers ... > > > > I completely agree. I think this thing needs to default to the > > existing atomic_t behaviour. > > I totally agree as well, the refcount_t facility as-is is unacceptable > for networking. Can we at least give a benchmark and have someone run numbers? We should be able to quantify these things.
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2017-03-20 14:30 +0100 |
| Subject | Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t |
| Message-ID | <tn5xM-5ik-35@gated-at.bofh.it> |
| In reply to | #1604357 |
On Mon, Mar 20, 2017 at 09:16:29PM +0800, Herbert Xu wrote: > On Mon, Mar 20, 2017 at 11:39:37AM +0100, Peter Zijlstra wrote: > > > > Can we at least give a benchmark and have someone run numbers? We should > > be able to quantify these things. > > Do you realise how many times this thing gets hit at 10Gb/s or > higher? Anyway, since you're proposing this change you should > demonstrate that it does not cause a performance regression. So what bench/setup do you want ran?
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2017-03-20 14:50 +0100 |
| Subject | Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t |
| Message-ID | <tn5R7-5oQ-5@gated-at.bofh.it> |
| In reply to | #1604563 |
On Mon, Mar 20, 2017 at 09:27:13PM +0800, Herbert Xu wrote: > On Mon, Mar 20, 2017 at 02:23:57PM +0100, Peter Zijlstra wrote: > > > > So what bench/setup do you want ran? > > You can start by counting how many cycles an atomic op takes > vs. how many cycles this new code takes. On what uarch? I think I tested hand coded asm version and it ended up about double the cycles for a cmpxchg loop vs the direct instruction on an IVB-EX (until the memory bus saturated, at which point they took the same). Newer parts will of course have different numbers, Can't we run some iperf on a 40gbe fiber loop or something? It would be very useful to have an actual workload we can run.
[toc] | [prev] | [next] | [standalone]
| From | Eric Dumazet <eric.dumazet@gmail.com> |
|---|---|
| Date | 2017-03-20 16:00 +0100 |
| Subject | Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t |
| Message-ID | <tn6WT-6aK-35@gated-at.bofh.it> |
| In reply to | #1604583 |
On Mon, 2017-03-20 at 07:51 -0700, Eric Dumazet wrote: > atomic_cmpxchg() on PowerPC is horribly more expensive because of the > added two SYNC instructions. Although I just saw that refcount was using atomic_cmpxchg_relaxed() Time to find some documentation (probably missing) or get some specs for this thing.
[toc] | [prev] | [next] | [standalone]
| From | Eric Dumazet <eric.dumazet@gmail.com> |
|---|---|
| Date | 2017-03-20 17:20 +0100 |
| Subject | Re: [PATCH 07/17] net: convert sock.sk_refcnt from atomic_t to refcount_t |
| Message-ID | <tn8ch-7du-9@gated-at.bofh.it> |
| In reply to | #1604666 |
On Mon, 2017-03-20 at 07:59 -0700, Eric Dumazet wrote:
> On Mon, 2017-03-20 at 07:51 -0700, Eric Dumazet wrote:
>
> > atomic_cmpxchg() on PowerPC is horribly more expensive because of the
> > added two SYNC instructions.
>
> Although I just saw that refcount was using atomic_cmpxchg_relaxed()
>
> Time to find some documentation (probably missing) or get some specs for
> this thing.
Interesting.
UDP ipv4 xmit path gets a ~25 % improvement on PPC with this patch.
( 20 concurrent netperf -t UDP_STREAM : 2.45 Mpps -> 3.07 Mpps )
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 8471dd116771462d149e1da2807e446b69b74bcc..9f14aebf0ae1f5f366cfff0fbf58c48603916bc7 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -497,14 +497,14 @@ u32 ip_idents_reserve(u32 hash, int segs)
u32 now = (u32)jiffies;
u32 new, delta = 0;
- if (old != now && cmpxchg(p_tstamp, old, now) == old)
+ if (old != now && cmpxchg_relaxed(p_tstamp, old, now) == old)
delta = prandom_u32_max(now - old);
/* Do not use atomic_add_return() as it makes UBSAN unhappy */
do {
old = (u32)atomic_read(p_id);
new = old + delta + segs;
- } while (atomic_cmpxchg(p_id, old, new) != old);
+ } while (atomic_cmpxchg_relaxed(p_id, old, new) != old);
return new - segs;
}
[toc] | [prev] | [next] | [standalone]
Page 1 of 3 [1] 2 3 Next page →
Back to top | Article view | linux.kernel
csiph-web