From: Hideo AOKI <haoki@redhat.com>
To: David Miller <davem@davemloft.net>,
Herbert Xu <herbert@gondor.apana.org.au>,
netdev <netdev@vger.kernel.org>
Cc: Takahiro Yasui <tyasui@redhat.com>,
Masami Hiramatsu <mhiramat@redhat.com>,
Satoshi Oshima <satoshi.oshima.fk@hitachi.com>,
Bill Fink <billfink@mindspring.com>,
Andi Kleen <andi@firstfloor.org>,
Evgeniy Polyakov <johnpol@2ka.mipt.ru>,
Stephen Hemminger <shemminger@linux-foundation.org>,
yoshfuji@linux-ipv6.org,
Yumiko Sugita <yumiko.sugita.yf@hitachi.com>,
haoki@redhat.com
Subject: [PATCH 2/4] [CORE]: datagram: basic memory accounting functions
Date: Mon, 17 Dec 2007 21:38:17 -0500 [thread overview]
Message-ID: <47673299.3010301@redhat.com> (raw)
In-Reply-To: <47673195.80004@redhat.com>
This patch includes changes in network core sub system for memory
accounting.
Memory scheduling, charging, uncharging and reclaiming functions are
added. These functions use sk_forward_alloc to store socket local
accounting. They currently support only datagram protocols.
sk_datagram_rfree() is a receive buffer detractor for datagram
protocols which are capable of protocol specific memory accounting.
Cc: Satoshi Oshima <satoshi.oshima.fk@hitachi.com>
signed-off-by: Takahiro Yasui <tyasui@redhat.com>
signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
signed-off-by: Hideo Aoki <haoki@redhat.com>
---
include/net/sock.h | 81 +++++++++++++++++++++++++++++++++++++++++++++++++
net/core/datagram.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 166 insertions(+)
diff -pruN net-2.6-udp-take11a1-p1/include/net/sock.h net-2.6-udp-take11a1-p2/include/net/sock.h
--- net-2.6-udp-take11a1-p1/include/net/sock.h 2007-12-11 10:54:53.000000000 -0500
+++ net-2.6-udp-take11a1-p2/include/net/sock.h 2007-12-17 14:42:39.000000000 -0500
@@ -750,6 +750,9 @@ static inline struct inode *SOCK_INODE(s
return &container_of(socket, struct socket_alloc, socket)->vfs_inode;
}
+/*
+ * Functions for memory accounting
+ */
extern void __sk_stream_mem_reclaim(struct sock *sk);
extern int sk_stream_mem_schedule(struct sock *sk, int size, int kind);
@@ -778,6 +781,82 @@ static inline int sk_stream_wmem_schedul
sk_stream_mem_schedule(sk, size, 0);
}
+extern void __sk_datagram_mem_reclaim(struct sock *sk);
+extern int sk_stream_mem_schedule(struct sock *sk, int size, int kind);
+
+#define SK_DATAGRAM_MEM_QUANTUM ((unsigned int)PAGE_SIZE)
+
+static inline int sk_datagram_pages(int amt)
+{
+ /* Cast to unsigned as an optimization, since amt is always positive. */
+ return DIV_ROUND_UP((unsigned int)amt, SK_DATAGRAM_MEM_QUANTUM);
+}
+
+extern int __sk_datagram_account_charge(struct sock *sk, int size, int kind);
+extern void __sk_datagram_mem_reclaim(struct sock *sk);
+extern int sk_datagram_mem_schedule(struct sock *sk, int size, int kind);
+
+static inline void sk_datagram_mem_reclaim(struct sock *sk)
+{
+ if (!sk->sk_prot->memory_allocated)
+ return;
+
+ __sk_datagram_mem_reclaim(sk);
+}
+
+static inline int sk_datagram_rmem_schedule(struct sock *sk, int size)
+{
+ return size <= sk->sk_forward_alloc ||
+ sk_datagram_mem_schedule(sk, size, 1);
+}
+
+static inline int sk_datagram_wmem_schedule(struct sock *sk, int size)
+{
+ return size <= sk->sk_forward_alloc ||
+ sk_datagram_mem_schedule(sk, size, 0);
+}
+
+static inline void sk_mem_reclaim(struct sock *sk)
+{
+ if (sk->sk_type == SOCK_DGRAM)
+ sk_datagram_mem_reclaim(sk);
+}
+
+static inline int sk_wmem_schedule(struct sock *sk, int size)
+{
+ if (sk->sk_type == SOCK_DGRAM)
+ return sk_datagram_wmem_schedule(sk, size);
+ else
+ return 1;
+}
+
+static inline int sk_account_wmem_charge(struct sock *sk, int size)
+{
+ /* account if protocol supports memory accounting. */
+ if (!sk->sk_prot->memory_allocated || sk->sk_type != SOCK_DGRAM)
+ return 1;
+
+ return __sk_datagram_account_charge(sk, size, 0);
+}
+
+static inline int sk_account_rmem_charge(struct sock *sk, int size)
+{
+ /* account if protocol supports memory accounting. */
+ if (!sk->sk_prot->memory_allocated || sk->sk_type != SOCK_DGRAM)
+ return 1;
+
+ return __sk_datagram_account_charge(sk, size, 1);
+}
+
+static inline void sk_account_uncharge(struct sock *sk, int size)
+{
+ /* account if protocol supports memory accounting. */
+ if (!sk->sk_prot->memory_allocated || sk->sk_type != SOCK_DGRAM)
+ return;
+
+ sk->sk_forward_alloc += size;
+}
+
/* Used by processes to "lock" a socket state, so that
* interrupts and bottom half handlers won't change it
* from under us. It essentially blocks any incoming
@@ -1166,6 +1245,8 @@ static inline void skb_set_owner_r(struc
atomic_add(skb->truesize, &sk->sk_rmem_alloc);
}
+extern void sk_datagram_rfree(struct sk_buff *skb);
+
extern void sk_reset_timer(struct sock *sk, struct timer_list* timer,
unsigned long expires);
diff -pruN net-2.6-udp-take11a1-p1/net/core/datagram.c net-2.6-udp-take11a1-p2/net/core/datagram.c
--- net-2.6-udp-take11a1-p1/net/core/datagram.c 2007-12-11 10:54:55.000000000 -0500
+++ net-2.6-udp-take11a1-p2/net/core/datagram.c 2007-12-17 14:42:39.000000000 -0500
@@ -484,6 +484,91 @@ fault:
}
/**
+ * sk_datagram_rfree - receive buffer detractor for datagram protocls
+ * @skb: skbuff
+ */
+void sk_datagram_rfree(struct sk_buff *skb)
+{
+ struct sock *sk = skb->sk;
+
+ skb_truesize_check(skb);
+ atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
+ sk_account_uncharge(sk, skb->truesize);
+ sk_datagram_mem_reclaim(sk);
+}
+EXPORT_SYMBOL(sk_datagram_rfree);
+
+
+/**
+ * __sk_datagram_account_charge - send buffer for datagram protocls
+ * @sk: socket
+ * @size: memory size to charge
+ * @kind: charge type
+ *
+ * If kind is 0, it means wmem allocation. Otherwise it means rmem
+ * allocation.
+ */
+int __sk_datagram_account_charge(struct sock *sk, int size, int kind)
+{
+ if ((kind && sk_datagram_rmem_schedule(sk, size)) ||
+ (!kind && sk_datagram_wmem_schedule(sk, size))) {
+ sk->sk_forward_alloc -= size;
+ return 1;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(__sk_datagram_account_charge);
+
+/**
+ * __sk_datagram_mem_reclaim - send buffer for datagram protocls
+ * @sk: socket
+ */
+void __sk_datagram_mem_reclaim(struct sock *sk)
+{
+ if (sk->sk_forward_alloc < SK_DATAGRAM_MEM_QUANTUM)
+ return;
+
+ atomic_sub(sk->sk_forward_alloc / SK_DATAGRAM_MEM_QUANTUM,
+ sk->sk_prot->memory_allocated);
+ sk->sk_forward_alloc &= SK_DATAGRAM_MEM_QUANTUM - 1;
+}
+EXPORT_SYMBOL(__sk_datagram_mem_reclaim);
+
+/**
+ * sk_datagram_mem_schedule - memory accounting for datagram protocls
+ * @sk: socket
+ * @size: memory size to allocate
+ * @kind: allocation type
+ *
+ * If kind is 0, it means wmem allocation. Otherwise it means rmem
+ * allocation.
+ */
+int sk_datagram_mem_schedule(struct sock *sk, int size, int kind)
+{
+ int amt;
+ struct proto *prot = sk->sk_prot;
+
+ /* Don't account and limit memory if protocol doesn't support. */
+ if (!prot->memory_allocated)
+ return 1;
+
+ amt = sk_datagram_pages(size);
+ if (atomic_add_return(amt, prot->memory_allocated) >
+ prot->sysctl_mem[0])
+ if ((kind && atomic_read(&sk->sk_rmem_alloc) + size >=
+ prot->sysctl_rmem[0]) ||
+ (!kind && atomic_read(&sk->sk_wmem_alloc) + size >=
+ prot->sysctl_wmem[0])) {
+ /* Undo changes. */
+ atomic_sub(amt, prot->memory_allocated);
+ return 0;
+ }
+ sk->sk_forward_alloc += amt * SK_DATAGRAM_MEM_QUANTUM;
+ return 1;
+}
+EXPORT_SYMBOL(sk_datagram_mem_schedule);
+
+/**
* datagram_poll - generic datagram poll
* @file: file struct
* @sock: socket
--
Hitachi Computer Products (America) Inc.
next prev parent reply other threads:[~2007-12-18 2:43 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-12-18 2:33 [PATCH 0/4] [UDP]: memory accounting and limitation (take 11) Hideo AOKI
2007-12-18 2:38 ` [PATCH 1/4] [UDP]: fix send buffer check Hideo AOKI
2007-12-20 11:31 ` David Miller
2007-12-21 3:43 ` Hideo AOKI
2007-12-18 2:38 ` Hideo AOKI [this message]
2007-12-19 3:21 ` [PATCH 2/4] [CORE]: datagram: basic memory accounting functions Hideo AOKI
2007-12-20 11:43 ` David Miller
2007-12-21 4:18 ` Hideo AOKI
2007-12-21 4:31 ` David Miller
2007-12-22 0:22 ` Hideo AOKI
2007-12-18 2:38 ` [PATCH 3/4] [UDP]: add udp_mem, udp_rmem_min and udp_wmem_min Hideo AOKI
2007-12-18 2:38 ` [PATCH 4/4] [UDP]: memory accounting in IPv4 Hideo AOKI
2007-12-20 11:44 ` David Miller
2007-12-21 3:58 ` Hideo AOKI
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=47673299.3010301@redhat.com \
--to=haoki@redhat.com \
--cc=andi@firstfloor.org \
--cc=billfink@mindspring.com \
--cc=davem@davemloft.net \
--cc=herbert@gondor.apana.org.au \
--cc=johnpol@2ka.mipt.ru \
--cc=mhiramat@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=satoshi.oshima.fk@hitachi.com \
--cc=shemminger@linux-foundation.org \
--cc=tyasui@redhat.com \
--cc=yoshfuji@linux-ipv6.org \
--cc=yumiko.sugita.yf@hitachi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.