Hello,
I updated patch set of UDP memory accounting and limitation.
The spin lock that I used in previous take was removed from datagram
memory accounting functions. As David commented, I used socket lock
and backlog processing to keep consistency of memory accounting like
TCP. I added socket lock to places where skbuff is freed, since the
locking is needed to change sk_forward_alloc only.
Moreover, I revised memory accounting functions. As Herbert commented,
I stopped using large inline function and tried to reduce amount of
inline functions.
The patch set was tested on net-2.6 tree.
Changelog take 10 -> take 11:
* stopped using spin lock in memory accounting function
* socket lock and backlog processing were used to avoid conflict
between receive system call processing and BH
* revised memory accounting functions
* stooped changing sock_queue_rcv_skb() and skb_set_owner_r()
* added __udp_queue_rcv_skb to set proper destructor
* removed udp_set_owner_r()
* removed reclaim in inet_sock_destruct()
Changelog take 9 -> take 10:
* supported using sk_forward_alloc
* introduced several memory accounting functions with spin lock
* changed detagram receive functions to be able to customize
destructor
* fixed accounting bugs in previous takes
Changelog take 8 -> take 9:
* introduced mem_schdeule functions for datargram protocols
* removed protocol check function, from patch set
* restructured patch set
Changelog take 7 -> take 8:
* sk_datagram_pages(): avoided using divide instruction
* udp_recvmsg(): fixed referring released truesize in accounting
Best regards,
Hideo Aoki
--
Hitachi Computer Products (America) Inc.
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 <redacted>
signed-off-by: Takahiro Yasui <redacted>
signed-off-by: Masami Hiramatsu <redacted>
signed-off-by: Hideo Aoki <redacted>
---
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
@@ -778,6 +781,82 @@ static inline int sk_stream_wmem_schedulsk_stream_mem_schedule(sk,size,0);}+externvoid__sk_datagram_mem_reclaim(structsock*sk);+externintsk_stream_mem_schedule(structsock*sk,intsize,intkind);++#define SK_DATAGRAM_MEM_QUANTUM ((unsigned int)PAGE_SIZE)++staticinlineintsk_datagram_pages(intamt)+{+/* Cast to unsigned as an optimization, since amt is always positive. */+returnDIV_ROUND_UP((unsignedint)amt,SK_DATAGRAM_MEM_QUANTUM);+}++externint__sk_datagram_account_charge(structsock*sk,intsize,intkind);+externvoid__sk_datagram_mem_reclaim(structsock*sk);+externintsk_datagram_mem_schedule(structsock*sk,intsize,intkind);++staticinlinevoidsk_datagram_mem_reclaim(structsock*sk)+{+if(!sk->sk_prot->memory_allocated)+return;++__sk_datagram_mem_reclaim(sk);+}++staticinlineintsk_datagram_rmem_schedule(structsock*sk,intsize)+{+returnsize<=sk->sk_forward_alloc||+sk_datagram_mem_schedule(sk,size,1);+}++staticinlineintsk_datagram_wmem_schedule(structsock*sk,intsize)+{+returnsize<=sk->sk_forward_alloc||+sk_datagram_mem_schedule(sk,size,0);+}++staticinlinevoidsk_mem_reclaim(structsock*sk)+{+if(sk->sk_type==SOCK_DGRAM)+sk_datagram_mem_reclaim(sk);+}++staticinlineintsk_wmem_schedule(structsock*sk,intsize)+{+if(sk->sk_type==SOCK_DGRAM)+returnsk_datagram_wmem_schedule(sk,size);+else+return1;+}++staticinlineintsk_account_wmem_charge(structsock*sk,intsize)+{+/* account if protocol supports memory accounting. */+if(!sk->sk_prot->memory_allocated||sk->sk_type!=SOCK_DGRAM)+return1;++return__sk_datagram_account_charge(sk,size,0);+}++staticinlineintsk_account_rmem_charge(structsock*sk,intsize)+{+/* account if protocol supports memory accounting. */+if(!sk->sk_prot->memory_allocated||sk->sk_type!=SOCK_DGRAM)+return1;++return__sk_datagram_account_charge(sk,size,1);+}++staticinlinevoidsk_account_uncharge(structsock*sk,intsize)+{+/* 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*interruptsandbottomhalfhandlerswon'tchangeit*fromunderus.Itessentiallyblocksanyincoming
This patch adds UDP memory usage accounting in IPv4.
Send buffer accounting is performed by IP layer, because skbuff is
allocated in the layer.
Receive buffer is charged, when the buffer successfully received.
Destructor of the buffer does uncharging and reclaiming, when the
buffer is freed. To set destructor at proper place, we use
__udp_queue_rcv_skb() instead of sock_queue_rcv_skb(). To maintain
consistency of memory accounting, socket lock is used to free receive
buffer in udp_recvmsg().
New packet will be add to backlog when the socket is used by user.
Cc: Satoshi Oshima <redacted>
signed-off-by: Takahiro Yasui <redacted>
signed-off-by: Masami Hiramatsu <redacted>
signed-off-by: Hideo Aoki <redacted>
---
ip_output.c | 46 +++++++++++++++++++++++++++++++++--
udp.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 119 insertions(+), 5 deletions(-)
diff -pruN net-2.6-udp-take11a1-p3/net/ipv4/ip_output.c net-2.6-udp-take11a1-p4/net/ipv4/ip_output.c
@@ -707,6 +707,7 @@ static inline int ip_ufo_append_data(str{structsk_buff*skb;interr;+intfirst_size,second_size;/* There is support for UDP fragmentation offload by network*device,socreateonesingleskbpacketcontainingcomplete
@@ -720,6 +721,11 @@ static inline int ip_ufo_append_data(strif(skb==NULL)returnerr;+if(!sk_account_wmem_charge(sk,skb->truesize)){+err=-ENOBUFS;+gotofail;+}+/* reserve space for Hardware header */skb_reserve(skb,hh_len);
@@ -736,6 +742,7 @@ static inline int ip_ufo_append_data(strskb->csum=0;sk->sk_sndmsg_off=0;}+first_size=skb->truesize;err=skb_append_datato_frags(sk,skb,getfrag,from,(length-transhdrlen));
@@ -743,6 +750,15 @@ static inline int ip_ufo_append_data(str/* specify the length of each IP datagram fragment*/skb_shinfo(skb)->gso_size=mtu-fragheaderlen;skb_shinfo(skb)->gso_type=SKB_GSO_UDP;++second_size=skb->truesize-first_size;+if(!sk_account_wmem_charge(sk,second_size)){+sk_account_uncharge(sk,first_size);+sk_mem_reclaim(sk);+err=-ENOBUFS;+gotofail;+}+__skb_queue_tail(&sk->sk_write_queue,skb);return0;
@@ -750,6 +766,7 @@ static inline int ip_ufo_append_data(str/* There is not enough support do UFO ,*sofollownormalpath*/+fail:kfree_skb(skb);returnerr;}
@@ -1213,13 +1246,14 @@ int ip_push_pending_frames(struct sock *structiphdr*iph;__be16df=0;__u8ttl;-interr=0;+interr=0,send_size;if((skb=__skb_dequeue(&sk->sk_write_queue))==NULL)gotoout;tail_skb=&(skb_shinfo(skb)->frag_list);/* move skb->data to ip header from ext header */+send_size=skb->truesize;if(skb->data<skb_network_header(skb))__skb_pull(skb,skb_network_offset(skb));while((tmp_skb=__skb_dequeue(&sk->sk_write_queue))!=NULL){
@@ -1229,6 +1263,7 @@ int ip_push_pending_frames(struct sock *skb->len+=tmp_skb->len;skb->data_len+=tmp_skb->len;skb->truesize+=tmp_skb->truesize;+send_size+=tmp_skb->truesize;__sock_put(tmp_skb->sk);tmp_skb->destructor=NULL;tmp_skb->sk=NULL;
@@ -1284,6 +1319,8 @@ int ip_push_pending_frames(struct sock */* Netfilter gets whole the not fragmented skb. */err=NF_HOOK(PF_INET,NF_IP_LOCAL_OUT,skb,NULL,skb->dst->dev,dst_output);+sk_account_uncharge(sk,send_size);+sk_mem_reclaim(sk);if(err){if(err>0)err=inet->recverr?net_xmit_errno(err):0;
@@ -934,6 +938,53 @@ int udp_disconnect(struct sock *sk, intreturn0;}+/**+*__udp_queue_rcv_skb-putnewskbtoreceivequeueofsocket+*@sk:socket+*@skb:skbuff+*+*Thisfunctionbasicallydoesthesamethingassock_queue_rcv_skb().+*Thedifferencetoitistosetanotherdestrucforwhichisableto+*domemoryaccouting.+*/+int__udp_queue_rcv_skb(structsock*sk,structsk_buff*skb)+{+interr=0;+intskb_len;++/* Cast skb->rcvbuf to unsigned... It's pointless, but reduces+numberofwarningswhencompilingwith-W--ANK+*/+if(atomic_read(&sk->sk_rmem_alloc)+skb->truesize>=+(unsigned)sk->sk_rcvbuf){+err=-ENOMEM;+gotoout;+}++err=sk_filter(sk,skb);+if(err)+gotoout;++skb->dev=NULL;+skb->sk=sk;+skb->destructor=sk_datagram_rfree;+atomic_add(skb->truesize,&sk->sk_rmem_alloc);++/* Cache the SKB length before we tack it onto the receive+*queue.Onceitisaddeditnolongerbelongstousand+*maybefreedbyotherthreadsofcontrolpullingpackets+*fromthequeue.+*/+skb_len=skb->len;++skb_queue_tail(&sk->sk_receive_queue,skb);++if(!sock_flag(sk,SOCK_DEAD))+sk->sk_data_ready(sk,skb_len);+out:+returnerr;+}+/* returns:*-1:error*0:success
@@ -1022,10 +1073,17 @@ int udp_queue_rcv_skb(struct sock * sk,gotodrop;}-if((rc=sock_queue_rcv_skb(sk,skb))<0){+if(!sk_account_rmem_charge(sk,skb->truesize)){+UDP_INC_STATS_BH(UDP_MIB_RCVBUFERRORS,up->pcflag);+gotodrop;+}++if((rc=__udp_queue_rcv_skb(sk,skb))<0){/* Note that an ENOMEM error is charged twice */if(rc==-ENOMEM)UDP_INC_STATS_BH(UDP_MIB_RCVBUFERRORS,up->pcflag);+sk_account_uncharge(sk,skb->truesize);+sk_datagram_mem_reclaim(sk);gotodrop;}
@@ -1068,7 +1126,15 @@ static int __udp4_lib_mcast_deliver(struskb1=skb_clone(skb,GFP_ATOMIC);if(skb1){-intret=udp_queue_rcv_skb(sk,skb1);+intret=0;++bh_lock_sock_nested(sk);+if(!sock_owned_by_user(sk))+ret=udp_queue_rcv_skb(sk,skb1);+else+sk_add_backlog(sk,skb1);+bh_unlock_sock(sk);+if(ret>0)/* we should probably re-process instead*ofdroppingpacketshere.*/
@@ -1161,7 +1227,13 @@ int __udp4_lib_rcv(struct sk_buff *skb,inet_iif(skb),udptable);if(sk!=NULL){-intret=udp_queue_rcv_skb(sk,skb);+intret=0;+bh_lock_sock_nested(sk);+if(!sock_owned_by_user(sk))+ret=udp_queue_rcv_skb(sk,skb);+else+sk_add_backlog(sk,skb);+bh_unlock_sock(sk);sock_put(sk);/* a return value > 0 means to resubmit the input, but
This patch adds sysctl parameters for customizing UDP memory accounting:
/proc/sys/net/ipv4/udp_mem
/proc/sys/net/ipv4/udp_rmem_min
/proc/sys/net/ipv4/udp_wmem_min
Udp_mem indicates number of pages which can be used for all UDP sockets.
Each UDP packet is dropped, when the number of pages for socket buffer is
beyond udp_mem and the socket already consumes minimum buffer.
This patch is also introduced memory_allocated variable for UDP protocol.
Cc: Satoshi Oshima <redacted>
signed-off-by: Hideo Aoki <redacted>
---
Documentation/networking/ip-sysctl.txt | 18 ++++++++++++++++++
include/net/udp.h | 9 +++++++++
net/ipv4/af_inet.c | 3 +++
net/ipv4/proc.c | 3 ++-
net/ipv4/sysctl_net_ipv4.c | 31 +++++++++++++++++++++++++++++++
net/ipv4/udp.c | 27 +++++++++++++++++++++++++++
6 files changed, 90 insertions(+), 1 deletion(-)
diff -pruN net-2.6-udp-take11a1-p2/Documentation/networking/ip-sysctl.txt net-2.6-udp-take11a1-p3/Documentation/networking/ip-sysctl.txt
@@ -446,6 +446,24 @@ tcp_dma_copybreak - INTEGER and CONFIG_NET_DMA is enabled. Default: 4096+UDP variables:++udp_mem - INTEGER+ Number of pages allowed for queueing by all UDP sockets.+ Default is calculated at boot time from amount of available memory.++udp_rmem_min - INTEGER+ Minimal size of receive buffer used by UDP sockets. Each UDP socket+ is able to use the size for receiving data, even if total pages of UDP+ sockets exceed udp_mem. The unit is byte.+ Default: 4096++udp_wmem_min - INTEGER+ Minimal size of send buffer used by UDP sockets. Each UDP socket is+ able to use the size for sending data, even if total pages of UDP+ sockets exceed udp_mem. The unit is byte.+ Default: 4096+ CIPSOv4 Variables: cipso_cache_enable - BOOLEAN
@@ -1449,6 +1455,10 @@ struct proto udp_prot = {.hash=udp_lib_hash,.unhash=udp_lib_unhash,.get_port=udp_v4_get_port,+.memory_allocated=&udp_memory_allocated,+.sysctl_mem=&sysctl_udp_mem,+.sysctl_wmem=&sysctl_udp_wmem_min,+.sysctl_rmem=&sysctl_udp_rmem_min,.obj_size=sizeof(structudp_sock),#ifdef CONFIG_COMPAT.compat_setsockopt=compat_udp_setsockopt,
@@ -1644,6 +1654,23 @@ void udp4_proc_exit(void)}#endif /* CONFIG_PROC_FS */+void__initudp_init(void)+{+unsignedlonglimit;++/* Set the pressure threshold up by the same strategy of TCP. It is a+*fractionofglobalmemorythatisupto1/2at256MB,decreasing+*towardzerowiththeamountofmemory,withafloorof128pages.+*/+limit=min(nr_all_pages,1UL<<(28-PAGE_SHIFT))>>(20-PAGE_SHIFT);+limit=(limit*(nr_all_pages>>(20-PAGE_SHIFT)))>>(PAGE_SHIFT-11);+limit=max(limit,128UL);+sysctl_udp_mem=limit/4*3;++sysctl_udp_rmem_min=SK_DATAGRAM_MEM_QUANTUM;+sysctl_udp_wmem_min=SK_DATAGRAM_MEM_QUANTUM;+}+EXPORT_SYMBOL(udp_disconnect);EXPORT_SYMBOL(udp_hash);EXPORT_SYMBOL(udp_hash_lock);
Hello,
I would like to update this patch since there were redundant extern declarations.
Regards,
Hideo
---
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 <redacted>
signed-off-by: Takahiro Yasui <redacted>
signed-off-by: Masami Hiramatsu <redacted>
signed-off-by: Hideo Aoki <redacted>
---
include/net/sock.h | 78 +++++++++++++++++++++++++++++++++++++++++++++++
net/core/datagram.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 163 insertions(+)
diff -pruN net-2.6-udp-take11a1-p1/include/net/sock.h net-2.6-udp-take11a1-p2/include/net/sock.h
@@ -778,6 +781,79 @@ static inline int sk_stream_wmem_schedulsk_stream_mem_schedule(sk,size,0);}+externint__sk_datagram_account_charge(structsock*sk,intsize,intkind);+externvoid__sk_datagram_mem_reclaim(structsock*sk);+externintsk_datagram_mem_schedule(structsock*sk,intsize,intkind);++#define SK_DATAGRAM_MEM_QUANTUM ((unsigned int)PAGE_SIZE)++staticinlineintsk_datagram_pages(intamt)+{+/* Cast to unsigned as an optimization, since amt is always positive. */+returnDIV_ROUND_UP((unsignedint)amt,SK_DATAGRAM_MEM_QUANTUM);+}++staticinlinevoidsk_datagram_mem_reclaim(structsock*sk)+{+if(!sk->sk_prot->memory_allocated)+return;++__sk_datagram_mem_reclaim(sk);+}++staticinlineintsk_datagram_rmem_schedule(structsock*sk,intsize)+{+returnsize<=sk->sk_forward_alloc||+sk_datagram_mem_schedule(sk,size,1);+}++staticinlineintsk_datagram_wmem_schedule(structsock*sk,intsize)+{+returnsize<=sk->sk_forward_alloc||+sk_datagram_mem_schedule(sk,size,0);+}++staticinlinevoidsk_mem_reclaim(structsock*sk)+{+if(sk->sk_type==SOCK_DGRAM)+sk_datagram_mem_reclaim(sk);+}++staticinlineintsk_wmem_schedule(structsock*sk,intsize)+{+if(sk->sk_type==SOCK_DGRAM)+returnsk_datagram_wmem_schedule(sk,size);+else+return1;+}++staticinlineintsk_account_rmem_charge(structsock*sk,intsize)+{+/* account if protocol supports memory accounting. */+if(!sk->sk_prot->memory_allocated||sk->sk_type!=SOCK_DGRAM)+return1;++return__sk_datagram_account_charge(sk,size,1);+}++staticinlineintsk_account_wmem_charge(structsock*sk,intsize)+{+/* account if protocol supports memory accounting. */+if(!sk->sk_prot->memory_allocated||sk->sk_type!=SOCK_DGRAM)+return1;++return__sk_datagram_account_charge(sk,size,0);+}++staticinlinevoidsk_account_uncharge(structsock*sk,intsize)+{+/* 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*interruptsandbottomhalfhandlerswon'tchangeit*fromunderus.Itessentiallyblocksanyincoming
If we are going to do this, we need to add the same check to
skb_append_datato_frags() which is invoked via ip_ufo_append_data().
We also have to be very careful in this area. One problem we had a
long time ago was that we would socket account when fragmenting an
outgoing frame. This was bogus because even if the socket had enough
space for one full sized frame, the packet send would fail because it
could not fit the space for both the original frame and the
fragmented copy of it.
This situation was cured by simply not enforcing accounting for the
fragmented copy. It is valid because after we fragment, we keep
the fragmented copy but free the original.
This doesn't apply directly to this specific patch, but it is
something to keep in mind when doing these changes.
From: David Miller <davem@davemloft.net> Date: 2007-12-20 11:43:05
From: Hideo AOKI <redacted>
Date: Mon, 17 Dec 2007 21:38:17 -0500
Why do we need seperate stream and datagram accounting functions?
Is it just to facilitate things like the following test?
+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;
+}
If so, this can be greatly improved.
All of these other functions are identical copies of the stream
counterparts, they should all be consolidated.
I still see a lot of special casing, instead of large pieces of common
code.
There should be one core set of functions that handle the memory
accounting, regardless of socket type. Maybe there is one spot where
something like sk->prot->doing_memory_accounting is tested, but that's
it.
I am still very dissatisfied with these changes. They are
full of special cases, because they mix generic facilities
(the socket memory accounting) with an unrelated issue
(we only support memory accounting for datagram sockets which
are actually UDP).
Also, the memory accounting is done at different parts in
the socket code paths for stream vs. datagram. This is why
everything is inconsistent, and, a mess.
What's funny is that I absolutely do not care if these changes are
perfect and pass every possible regression test. Rather, I'm more
concerned that this thing is designed correctly and will allow us to
have one core set of memory accounting functions regardless of socket
type. As it is coded now, we have two sets of code paths to
fix, two ways of doing the socket accounting, and therefore twice
as much code to maintain and debug.
The whole thing needs to be consistent and without special cases.
The "protocol supports memory accounting" test can be performed, as
you did in this patch, by simply checking if
sk->sk_prot->memory_allocated is non-NULL.
This patch adds UDP memory usage accounting in IPv4.
Send buffer accounting is performed by IP layer, because skbuff is
allocated in the layer.
Receive buffer is charged, when the buffer successfully received.
Destructor of the buffer does uncharging and reclaiming, when the
buffer is freed. To set destructor at proper place, we use
__udp_queue_rcv_skb() instead of sock_queue_rcv_skb(). To maintain
consistency of memory accounting, socket lock is used to free receive
buffer in udp_recvmsg().
New packet will be add to backlog when the socket is used by user.
Cc: Satoshi Oshima <redacted>
signed-off-by: Takahiro Yasui <redacted>
signed-off-by: Masami Hiramatsu <redacted>
signed-off-by: Hideo Aoki <redacted>
We can't accept these changes, even once the other issues
are fixed, until IPV6 is supported as well.
It's pointless to support proper UDP memory accounting only
in IPV4 and not in IPV6 as well.
If we are going to do this, we need to add the same check to
skb_append_datato_frags() which is invoked via ip_ufo_append_data().
We also have to be very careful in this area. One problem we had a
long time ago was that we would socket account when fragmenting an
outgoing frame. This was bogus because even if the socket had enough
space for one full sized frame, the packet send would fail because it
could not fit the space for both the original frame and the
fragmented copy of it.
This situation was cured by simply not enforcing accounting for the
fragmented copy. It is valid because after we fragment, we keep
the fragmented copy but free the original.
This doesn't apply directly to this specific patch, but it is
something to keep in mind when doing these changes.
Hello,
Thank you for sharing your experience.
Let me investigate this code and skb_append_datato_frags().
I'll include the check code in next patch set if it is really needed.
Regards,
Hideo
--
Hitachi Computer Products (America) Inc.
This patch adds UDP memory usage accounting in IPv4.
We can't accept these changes, even once the other issues
are fixed, until IPV6 is supported as well.
It's pointless to support proper UDP memory accounting only
in IPV4 and not in IPV6 as well.
I understood. I'll develop IPv6 UDP memory accounting as well and
include it in next UDP memory accounting patch set submission.
Many thanks,
Hideo
--
Hitachi Computer Products (America) Inc.
Hello,
Thank you so much for your comments.
David Miller wrote:
All of these other functions are identical copies of the stream
counterparts, they should all be consolidated.
I still see a lot of special casing, instead of large pieces of common
code.
There should be one core set of functions that handle the memory
accounting, regardless of socket type. Maybe there is one spot where
something like sk->prot->doing_memory_accounting is tested, but that's
it.
I understood. I'll re-write my patch set to make memory accounting
core functions.
Also, the memory accounting is done at different parts in
the socket code paths for stream vs. datagram. This is why
everything is inconsistent, and, a mess.
Could you tell me more detailed information?
Does this comment mean interface and usage of memory accounting functions?
If so, I'll consolidate functions like sk_stream_set_owner_r() and
sk_stream_free_skb(). And, I may have to use memory accounting functions in
memory allocating functions like sk_stream_alloc_pskb() as possible
instead of inside of socket operating functions.
Or, does the comment mean that send buffer accounting in IP layer
(e.g. ip_append_data()) is wrong?
Anyway, in next patch set, I'm going to consolidate mem_schedule
functions and mem_reclaim functions. To do so, some of memory
accounting functions for stream protocols will be renamed or
be moved to core/sock.c from core/stream.c.
I would like to know what kind of enhancement must be needed for
memory accounting core functions.
Again, thank you for taking your time to review this feature.
Best regards,
Hideo
--
Hitachi Computer Products (America) Inc.
Also, the memory accounting is done at different parts in
the socket code paths for stream vs. datagram. This is why
everything is inconsistent, and, a mess.
Could you tell me more detailed information?
I think the core thing is that TCP and INET protocols call into
the memory accounting internally, either inside their own code
paths or with inet_*() helpers.
This is versus what we really want is everything happening via generic
sk_foo() helpers.
If that's what's happening already, great, just consolidate the
datagram vs. stream stuff and it should be good.
Also, the memory accounting is done at different parts in
the socket code paths for stream vs. datagram. This is why
everything is inconsistent, and, a mess.
Could you tell me more detailed information?
I think the core thing is that TCP and INET protocols call into
the memory accounting internally, either inside their own code
paths or with inet_*() helpers.
This is versus what we really want is everything happening via generic
sk_foo() helpers.
If that's what's happening already, great, just consolidate the
datagram vs. stream stuff and it should be good.
Thank you for the explanation.
I'll do my best.
Regards,
Hideo
--
Hitachi Computer Products (America) Inc.