Commit 5d18286c authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo Committed by Arnaldo Carvalho de Melo

[NET] first bits of net/core/stream.c

Move tcp sk_wmem_queued related functions to net/core/stream.c, will be
used by other SOCK_STREAM protocols, starting with LLC.

Also move the tcp_charge_skb to sock.h, for the same reasons.
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@conectiva.com.br>
parent 5d746e6a
...@@ -413,6 +413,21 @@ static inline int sk_acceptq_is_full(struct sock *sk) ...@@ -413,6 +413,21 @@ static inline int sk_acceptq_is_full(struct sock *sk)
return sk->sk_ack_backlog > sk->sk_max_ack_backlog; return sk->sk_ack_backlog > sk->sk_max_ack_backlog;
} }
/*
* Compute minimal free write space needed to queue new packets.
*/
static inline int sk_stream_min_wspace(struct sock *sk)
{
return sk->sk_wmem_queued / 2;
}
static inline int sk_stream_wspace(struct sock *sk)
{
return sk->sk_sndbuf - sk->sk_wmem_queued;
}
extern void sk_stream_write_space(struct sock *sk);
/* The per-socket spinlock must be held here. */ /* The per-socket spinlock must be held here. */
#define sk_add_backlog(__sk, __skb) \ #define sk_add_backlog(__sk, __skb) \
do { if (!(__sk)->sk_backlog.tail) { \ do { if (!(__sk)->sk_backlog.tail) { \
...@@ -902,6 +917,11 @@ sk_dst_check(struct sock *sk, u32 cookie) ...@@ -902,6 +917,11 @@ sk_dst_check(struct sock *sk, u32 cookie)
return dst; return dst;
} }
static inline void sk_charge_skb(struct sock *sk, struct sk_buff *skb)
{
sk->sk_wmem_queued += skb->truesize;
sk->sk_forward_alloc -= skb->truesize;
}
/* /*
* Queue a received datagram if it will fit. Stream and sequenced * Queue a received datagram if it will fit. Stream and sequenced
......
...@@ -870,7 +870,6 @@ extern void tcp_close(struct sock *sk, ...@@ -870,7 +870,6 @@ extern void tcp_close(struct sock *sk,
long timeout); long timeout);
extern struct sock * tcp_accept(struct sock *sk, int flags, int *err); extern struct sock * tcp_accept(struct sock *sk, int flags, int *err);
extern unsigned int tcp_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait); extern unsigned int tcp_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait);
extern void tcp_write_space(struct sock *sk);
extern int tcp_getsockopt(struct sock *sk, int level, extern int tcp_getsockopt(struct sock *sk, int level,
int optname, int optname,
...@@ -1195,21 +1194,6 @@ struct tcp_skb_cb { ...@@ -1195,21 +1194,6 @@ struct tcp_skb_cb {
#include <net/tcp_ecn.h> #include <net/tcp_ecn.h>
/*
* Compute minimal free write space needed to queue new packets.
*/
static inline int tcp_min_write_space(struct sock *sk)
{
return sk->sk_wmem_queued / 2;
}
static inline int tcp_wspace(struct sock *sk)
{
return sk->sk_sndbuf - sk->sk_wmem_queued;
}
/* This determines how many packets are "in the network" to the best /* This determines how many packets are "in the network" to the best
* of our knowledge. In many cases it is conservative, but where * of our knowledge. In many cases it is conservative, but where
* detailed information is available from the receiver (via SACK * detailed information is available from the receiver (via SACK
...@@ -1899,12 +1883,6 @@ static inline void tcp_free_skb(struct sock *sk, struct sk_buff *skb) ...@@ -1899,12 +1883,6 @@ static inline void tcp_free_skb(struct sock *sk, struct sk_buff *skb)
__kfree_skb(skb); __kfree_skb(skb);
} }
static inline void tcp_charge_skb(struct sock *sk, struct sk_buff *skb)
{
sk->sk_wmem_queued += skb->truesize;
sk->sk_forward_alloc -= skb->truesize;
}
extern void __tcp_mem_reclaim(struct sock *sk); extern void __tcp_mem_reclaim(struct sock *sk);
extern int tcp_mem_schedule(struct sock *sk, int size, int kind); extern int tcp_mem_schedule(struct sock *sk, int size, int kind);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Makefile for the Linux networking core. # Makefile for the Linux networking core.
# #
obj-y := sock.o skbuff.o iovec.o datagram.o scm.o obj-y := sock.o skbuff.o iovec.o datagram.o stream.o scm.o
obj-$(CONFIG_SYSCTL) += sysctl_net_core.o obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
......
/*
* SUCS NET3:
*
* Generic stream handling routines. These are generic for most
* protocols. Even IP. Tonight 8-).
* This is used because TCP, LLC (others too) layer all have mostly
* identical sendmsg() and recvmsg() code.
* So we (will) share it here.
*
* Authors: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
* (from old tcp.c code)
* Alan Cox <alan@redhat.com> (Borrowed comments 8-))
*/
#include <linux/module.h>
#include <linux/net.h>
#include <linux/signal.h>
#include <linux/wait.h>
#include <net/sock.h>
/**
* sk_stream_write_space - stream socket write_space callback.
* sk - socket
*
* FIXME: write proper description
*/
void sk_stream_write_space(struct sock *sk)
{
struct socket *sock = sk->sk_socket;
if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk) && sock) {
clear_bit(SOCK_NOSPACE, &sock->flags);
if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
wake_up_interruptible(sk->sk_sleep);
if (sock->fasync_list && !(sk->sk_shutdown & SEND_SHUTDOWN))
sock_wake_async(sock, 2, POLL_OUT);
}
}
EXPORT_SYMBOL(sk_stream_write_space);
...@@ -447,7 +447,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) ...@@ -447,7 +447,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
mask |= POLLIN | POLLRDNORM; mask |= POLLIN | POLLRDNORM;
if (!(sk->sk_shutdown & SEND_SHUTDOWN)) { if (!(sk->sk_shutdown & SEND_SHUTDOWN)) {
if (tcp_wspace(sk) >= tcp_min_write_space(sk)) { if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) {
mask |= POLLOUT | POLLWRNORM; mask |= POLLOUT | POLLWRNORM;
} else { /* send SIGIO later */ } else { /* send SIGIO later */
set_bit(SOCK_ASYNC_NOSPACE, set_bit(SOCK_ASYNC_NOSPACE,
...@@ -458,7 +458,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) ...@@ -458,7 +458,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
* wspace test but before the flags are set, * wspace test but before the flags are set,
* IO signal will be lost. * IO signal will be lost.
*/ */
if (tcp_wspace(sk) >= tcp_min_write_space(sk)) if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk))
mask |= POLLOUT | POLLWRNORM; mask |= POLLOUT | POLLWRNORM;
} }
} }
...@@ -469,24 +469,6 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) ...@@ -469,24 +469,6 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
return mask; return mask;
} }
/*
* TCP socket write_space callback.
*/
void tcp_write_space(struct sock *sk)
{
struct socket *sock = sk->sk_socket;
if (tcp_wspace(sk) >= tcp_min_write_space(sk) && sock) {
clear_bit(SOCK_NOSPACE, &sock->flags);
if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
wake_up_interruptible(sk->sk_sleep);
if (sock->fasync_list && !(sk->sk_shutdown & SEND_SHUTDOWN))
sock_wake_async(sock, 2, POLL_OUT);
}
}
int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
{ {
struct tcp_opt *tp = tcp_sk(sk); struct tcp_opt *tp = tcp_sk(sk);
...@@ -796,7 +778,7 @@ static inline void skb_entail(struct sock *sk, struct tcp_opt *tp, ...@@ -796,7 +778,7 @@ static inline void skb_entail(struct sock *sk, struct tcp_opt *tp,
TCP_SKB_CB(skb)->flags = TCPCB_FLAG_ACK; TCP_SKB_CB(skb)->flags = TCPCB_FLAG_ACK;
TCP_SKB_CB(skb)->sacked = 0; TCP_SKB_CB(skb)->sacked = 0;
__skb_queue_tail(&sk->sk_write_queue, skb); __skb_queue_tail(&sk->sk_write_queue, skb);
tcp_charge_skb(sk, skb); sk_charge_skb(sk, skb);
if (!tp->send_head) if (!tp->send_head)
tp->send_head = skb; tp->send_head = skb;
else if (tp->nonagle&TCP_NAGLE_PUSH) else if (tp->nonagle&TCP_NAGLE_PUSH)
...@@ -2635,4 +2617,3 @@ EXPORT_SYMBOL(tcp_shutdown); ...@@ -2635,4 +2617,3 @@ EXPORT_SYMBOL(tcp_shutdown);
EXPORT_SYMBOL(tcp_sockets_allocated); EXPORT_SYMBOL(tcp_sockets_allocated);
EXPORT_SYMBOL(tcp_statistics); EXPORT_SYMBOL(tcp_statistics);
EXPORT_SYMBOL(tcp_timewait_cachep); EXPORT_SYMBOL(tcp_timewait_cachep);
EXPORT_SYMBOL(tcp_write_space);
...@@ -2081,7 +2081,7 @@ static int tcp_v4_init_sock(struct sock *sk) ...@@ -2081,7 +2081,7 @@ static int tcp_v4_init_sock(struct sock *sk)
sk->sk_state = TCP_CLOSE; sk->sk_state = TCP_CLOSE;
sk->sk_write_space = tcp_write_space; sk->sk_write_space = sk_stream_write_space;
sk->sk_use_write_queue = 1; sk->sk_use_write_queue = 1;
tp->af_specific = &ipv4_specific; tp->af_specific = &ipv4_specific;
......
...@@ -720,7 +720,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req, ...@@ -720,7 +720,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL; newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL;
newsk->sk_callback_lock = RW_LOCK_UNLOCKED; newsk->sk_callback_lock = RW_LOCK_UNLOCKED;
skb_queue_head_init(&newsk->sk_error_queue); skb_queue_head_init(&newsk->sk_error_queue);
newsk->sk_write_space = tcp_write_space; newsk->sk_write_space = sk_stream_write_space;
if ((filter = newsk->sk_filter) != NULL) if ((filter = newsk->sk_filter) != NULL)
sk_filter_charge(newsk, filter); sk_filter_charge(newsk, filter);
......
...@@ -326,7 +326,7 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb) ...@@ -326,7 +326,7 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb)
/* Advance write_seq and place onto the write_queue. */ /* Advance write_seq and place onto the write_queue. */
tp->write_seq = TCP_SKB_CB(skb)->end_seq; tp->write_seq = TCP_SKB_CB(skb)->end_seq;
__skb_queue_tail(&sk->sk_write_queue, skb); __skb_queue_tail(&sk->sk_write_queue, skb);
tcp_charge_skb(sk, skb); sk_charge_skb(sk, skb);
/* Queue it, remembering where we must start sending. */ /* Queue it, remembering where we must start sending. */
if (tp->send_head == NULL) if (tp->send_head == NULL)
...@@ -439,7 +439,7 @@ static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len) ...@@ -439,7 +439,7 @@ static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len)
buff = tcp_alloc_skb(sk, nsize, GFP_ATOMIC); buff = tcp_alloc_skb(sk, nsize, GFP_ATOMIC);
if (buff == NULL) if (buff == NULL)
return -ENOMEM; /* We'll just try again later. */ return -ENOMEM; /* We'll just try again later. */
tcp_charge_skb(sk, buff); sk_charge_skb(sk, buff);
/* Correct the sequence numbers. */ /* Correct the sequence numbers. */
TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len;
...@@ -1169,7 +1169,7 @@ int tcp_send_synack(struct sock *sk) ...@@ -1169,7 +1169,7 @@ int tcp_send_synack(struct sock *sk)
__skb_unlink(skb, &sk->sk_write_queue); __skb_unlink(skb, &sk->sk_write_queue);
__skb_queue_head(&sk->sk_write_queue, nskb); __skb_queue_head(&sk->sk_write_queue, nskb);
tcp_free_skb(sk, skb); tcp_free_skb(sk, skb);
tcp_charge_skb(sk, nskb); sk_charge_skb(sk, nskb);
skb = nskb; skb = nskb;
} }
...@@ -1329,7 +1329,7 @@ int tcp_connect(struct sock *sk) ...@@ -1329,7 +1329,7 @@ int tcp_connect(struct sock *sk)
TCP_SKB_CB(buff)->when = tcp_time_stamp; TCP_SKB_CB(buff)->when = tcp_time_stamp;
tp->retrans_stamp = TCP_SKB_CB(buff)->when; tp->retrans_stamp = TCP_SKB_CB(buff)->when;
__skb_queue_tail(&sk->sk_write_queue, buff); __skb_queue_tail(&sk->sk_write_queue, buff);
tcp_charge_skb(sk, buff); sk_charge_skb(sk, buff);
tp->packets_out++; tp->packets_out++;
tcp_transmit_skb(sk, skb_clone(buff, GFP_KERNEL)); tcp_transmit_skb(sk, skb_clone(buff, GFP_KERNEL));
TCP_INC_STATS(TcpActiveOpens); TCP_INC_STATS(TcpActiveOpens);
......
...@@ -1879,7 +1879,7 @@ static int tcp_v6_init_sock(struct sock *sk) ...@@ -1879,7 +1879,7 @@ static int tcp_v6_init_sock(struct sock *sk)
tp->af_specific = &ipv6_specific; tp->af_specific = &ipv6_specific;
sk->sk_write_space = tcp_write_space; sk->sk_write_space = sk_stream_write_space;
sk->sk_use_write_queue = 1; sk->sk_use_write_queue = 1;
sk->sk_sndbuf = sysctl_tcp_wmem[1]; sk->sk_sndbuf = sysctl_tcp_wmem[1];
......
...@@ -125,7 +125,7 @@ svc_sock_wspace(struct svc_sock *svsk) ...@@ -125,7 +125,7 @@ svc_sock_wspace(struct svc_sock *svsk)
int wspace; int wspace;
if (svsk->sk_sock->type == SOCK_STREAM) if (svsk->sk_sock->type == SOCK_STREAM)
wspace = tcp_wspace(svsk->sk_sk); wspace = sk_stream_wspace(svsk->sk_sk);
else else
wspace = sock_wspace(svsk->sk_sk); wspace = sock_wspace(svsk->sk_sk);
......
...@@ -1086,8 +1086,8 @@ xprt_write_space(struct sock *sk) ...@@ -1086,8 +1086,8 @@ xprt_write_space(struct sock *sk)
/* Wait until we have enough socket memory */ /* Wait until we have enough socket memory */
if (xprt->stream) { if (xprt->stream) {
/* from net/ipv4/tcp.c:tcp_write_space */ /* from net/core/stream.c:sk_stream_write_space */
if (tcp_wspace(sk) < tcp_min_write_space(sk)) if (sk_stream_wspace(sk) < sk_stream_min_wspace(sk))
goto out; goto out;
} else { } else {
/* from net/core/sock.c:sock_def_write_space */ /* from net/core/sock.c:sock_def_write_space */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment