aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Caulfield <patrick@tykepenguin.com>2005-09-01 20:43:45 -0400
committerDavid S. Miller <davem@davemloft.net>2005-09-01 20:43:45 -0400
commit12a49ffd842bf5b07c62eaabf178703ce4fe09d7 (patch)
tree7b545e72c8bc1d11aef96dba359221f7174d752b
parenteb6f1160ddb2fdadf50f350da79d0796c37f17e2 (diff)
[DECNET]: Tidy send side socket SKB allocation.
Patch from Steve Whitehouse which I've vetted and tested: "This patch is really intended has a move towards fixing the sendmsg/recvmsg functions in various ways so that we will finally have working nagle. Also reduces code duplication." Signed-off-by: Patrick Caulfield <patrick@tykepenguin.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/decnet/af_decnet.c40
-rw-r--r--net/decnet/dn_nsp_out.c63
2 files changed, 33 insertions, 70 deletions
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 621680f127af..348f36b529f7 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -1876,8 +1876,27 @@ static inline unsigned int dn_current_mss(struct sock *sk, int flags)
1876 return mss_now; 1876 return mss_now;
1877} 1877}
1878 1878
1879/*
1880 * N.B. We get the timeout wrong here, but then we always did get it
1881 * wrong before and this is another step along the road to correcting
1882 * it. It ought to get updated each time we pass through the routine,
1883 * but in practise it probably doesn't matter too much for now.
1884 */
1885static inline struct sk_buff *dn_alloc_send_pskb(struct sock *sk,
1886 unsigned long datalen, int noblock,
1887 int *errcode)
1888{
1889 struct sk_buff *skb = sock_alloc_send_skb(sk, datalen,
1890 noblock, errcode);
1891 if (skb) {
1892 skb->protocol = __constant_htons(ETH_P_DNA_RT);
1893 skb->pkt_type = PACKET_OUTGOING;
1894 }
1895 return skb;
1896}
1897
1879static int dn_sendmsg(struct kiocb *iocb, struct socket *sock, 1898static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
1880 struct msghdr *msg, size_t size) 1899 struct msghdr *msg, size_t size)
1881{ 1900{
1882 struct sock *sk = sock->sk; 1901 struct sock *sk = sock->sk;
1883 struct dn_scp *scp = DN_SK(sk); 1902 struct dn_scp *scp = DN_SK(sk);
@@ -1892,7 +1911,7 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
1892 struct dn_skb_cb *cb; 1911 struct dn_skb_cb *cb;
1893 size_t len; 1912 size_t len;
1894 unsigned char fctype; 1913 unsigned char fctype;
1895 long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); 1914 long timeo;
1896 1915
1897 if (flags & ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL|MSG_MORE|MSG_CMSG_COMPAT)) 1916 if (flags & ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL|MSG_MORE|MSG_CMSG_COMPAT))
1898 return -EOPNOTSUPP; 1917 return -EOPNOTSUPP;
@@ -1900,18 +1919,21 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
1900 if (addr_len && (addr_len != sizeof(struct sockaddr_dn))) 1919 if (addr_len && (addr_len != sizeof(struct sockaddr_dn)))
1901 return -EINVAL; 1920 return -EINVAL;
1902 1921
1922 lock_sock(sk);
1923 timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
1903 /* 1924 /*
1904 * The only difference between stream sockets and sequenced packet 1925 * The only difference between stream sockets and sequenced packet
1905 * sockets is that the stream sockets always behave as if MSG_EOR 1926 * sockets is that the stream sockets always behave as if MSG_EOR
1906 * has been set. 1927 * has been set.
1907 */ 1928 */
1908 if (sock->type == SOCK_STREAM) { 1929 if (sock->type == SOCK_STREAM) {
1909 if (flags & MSG_EOR) 1930 if (flags & MSG_EOR) {
1910 return -EINVAL; 1931 err = -EINVAL;
1932 goto out;
1933 }
1911 flags |= MSG_EOR; 1934 flags |= MSG_EOR;
1912 } 1935 }
1913 1936
1914 lock_sock(sk);
1915 1937
1916 err = dn_check_state(sk, addr, addr_len, &timeo, flags); 1938 err = dn_check_state(sk, addr, addr_len, &timeo, flags);
1917 if (err) 1939 if (err)
@@ -1980,8 +2002,12 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
1980 2002
1981 /* 2003 /*
1982 * Get a suitably sized skb. 2004 * Get a suitably sized skb.
2005 * 64 is a bit of a hack really, but its larger than any
2006 * link-layer headers and has served us well as a good
2007 * guess as to their real length.
1983 */ 2008 */
1984 skb = dn_alloc_send_skb(sk, &len, flags & MSG_DONTWAIT, timeo, &err); 2009 skb = dn_alloc_send_pskb(sk, len + 64 + DN_MAX_NSP_DATA_HEADER,
2010 flags & MSG_DONTWAIT, &err);
1985 2011
1986 if (err) 2012 if (err)
1987 break; 2013 break;
@@ -1991,7 +2017,7 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
1991 2017
1992 cb = DN_SKB_CB(skb); 2018 cb = DN_SKB_CB(skb);
1993 2019
1994 skb_reserve(skb, DN_MAX_NSP_DATA_HEADER); 2020 skb_reserve(skb, 64 + DN_MAX_NSP_DATA_HEADER);
1995 2021
1996 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { 2022 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
1997 err = -EFAULT; 2023 err = -EFAULT;
diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c
index e0bebf4bbcad..53633d352868 100644
--- a/net/decnet/dn_nsp_out.c
+++ b/net/decnet/dn_nsp_out.c
@@ -137,69 +137,6 @@ struct sk_buff *dn_alloc_skb(struct sock *sk, int size, int pri)
137} 137}
138 138
139/* 139/*
140 * Wrapper for the above, for allocs of data skbs. We try and get the
141 * whole size thats been asked for (plus 11 bytes of header). If this
142 * fails, then we try for any size over 16 bytes for SOCK_STREAMS.
143 */
144struct sk_buff *dn_alloc_send_skb(struct sock *sk, size_t *size, int noblock, long timeo, int *err)
145{
146 int space;
147 int len;
148 struct sk_buff *skb = NULL;
149
150 *err = 0;
151
152 while(skb == NULL) {
153 if (signal_pending(current)) {
154 *err = sock_intr_errno(timeo);
155 break;
156 }
157
158 if (sk->sk_shutdown & SEND_SHUTDOWN) {
159 *err = EINVAL;
160 break;
161 }
162
163 if (sk->sk_err)
164 break;
165
166 len = *size + 11;
167 space = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
168
169 if (space < len) {
170 if ((sk->sk_socket->type == SOCK_STREAM) &&
171 (space >= (16 + 11)))
172 len = space;
173 }
174
175 if (space < len) {
176 set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
177 if (noblock) {
178 *err = EWOULDBLOCK;
179 break;
180 }
181
182 clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
183 SOCK_SLEEP_PRE(sk)
184
185 if ((sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc)) <
186 len)
187 schedule();
188
189 SOCK_SLEEP_POST(sk)
190 continue;
191 }
192
193 if ((skb = dn_alloc_skb(sk, len, sk->sk_allocation)) == NULL)
194 continue;
195
196 *size = len - 11;
197 }
198
199 return skb;
200}
201
202/*
203 * Calculate persist timer based upon the smoothed round 140 * Calculate persist timer based upon the smoothed round
204 * trip time and the variance. Backoff according to the 141 * trip time and the variance. Backoff according to the
205 * nsp_backoff[] array. 142 * nsp_backoff[] array.