ip_output.c (1f901d59a5489e4dc7fdd339808d89b89f35483e) | ip_output.c (694aba690de062cf27b28a5e56e7a5a7185b0a1c) |
---|---|
1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * The Internet Protocol (IP) output module. 7 * 8 * Authors: Ross Biro --- 862 unchanged lines hidden (view full) --- 871 int exthdrlen; 872 int mtu; 873 int copy; 874 int err; 875 int offset = 0; 876 unsigned int maxfraglen, fragheaderlen, maxnonfragsize; 877 int csummode = CHECKSUM_NONE; 878 struct rtable *rt = (struct rtable *)cork->dst; | 1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * The Internet Protocol (IP) output module. 7 * 8 * Authors: Ross Biro --- 862 unchanged lines hidden (view full) --- 871 int exthdrlen; 872 int mtu; 873 int copy; 874 int err; 875 int offset = 0; 876 unsigned int maxfraglen, fragheaderlen, maxnonfragsize; 877 int csummode = CHECKSUM_NONE; 878 struct rtable *rt = (struct rtable *)cork->dst; |
879 unsigned int wmem_alloc_delta = 0; |
|
879 u32 tskey = 0; 880 881 skb = skb_peek_tail(queue); 882 883 exthdrlen = !skb ? rt->dst.header_len : 0; 884 mtu = cork->fragsize; 885 if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP && 886 sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) --- 79 unchanged lines hidden (view full) --- 966 alloclen += rt->dst.trailer_len; 967 968 if (transhdrlen) { 969 skb = sock_alloc_send_skb(sk, 970 alloclen + hh_len + 15, 971 (flags & MSG_DONTWAIT), &err); 972 } else { 973 skb = NULL; | 880 u32 tskey = 0; 881 882 skb = skb_peek_tail(queue); 883 884 exthdrlen = !skb ? rt->dst.header_len : 0; 885 mtu = cork->fragsize; 886 if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP && 887 sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) --- 79 unchanged lines hidden (view full) --- 967 alloclen += rt->dst.trailer_len; 968 969 if (transhdrlen) { 970 skb = sock_alloc_send_skb(sk, 971 alloclen + hh_len + 15, 972 (flags & MSG_DONTWAIT), &err); 973 } else { 974 skb = NULL; |
974 if (refcount_read(&sk->sk_wmem_alloc) <= | 975 if (refcount_read(&sk->sk_wmem_alloc) + wmem_alloc_delta <= |
975 2 * sk->sk_sndbuf) | 976 2 * sk->sk_sndbuf) |
976 skb = sock_wmalloc(sk, 977 alloclen + hh_len + 15, 1, 978 sk->sk_allocation); | 977 skb = alloc_skb(alloclen + hh_len + 15, 978 sk->sk_allocation); |
979 if (unlikely(!skb)) 980 err = -ENOBUFS; 981 } 982 if (!skb) 983 goto error; 984 985 /* 986 * Fill in the control structures --- 41 unchanged lines hidden (view full) --- 1028 csummode = CHECKSUM_NONE; 1029 1030 if ((flags & MSG_CONFIRM) && !skb_prev) 1031 skb_set_dst_pending_confirm(skb, 1); 1032 1033 /* 1034 * Put the packet on the pending queue. 1035 */ | 979 if (unlikely(!skb)) 980 err = -ENOBUFS; 981 } 982 if (!skb) 983 goto error; 984 985 /* 986 * Fill in the control structures --- 41 unchanged lines hidden (view full) --- 1028 csummode = CHECKSUM_NONE; 1029 1030 if ((flags & MSG_CONFIRM) && !skb_prev) 1031 skb_set_dst_pending_confirm(skb, 1); 1032 1033 /* 1034 * Put the packet on the pending queue. 1035 */ |
1036 if (!skb->destructor) { 1037 skb->destructor = sock_wfree; 1038 skb->sk = sk; 1039 wmem_alloc_delta += skb->truesize; 1040 } |
|
1036 __skb_queue_tail(queue, skb); 1037 continue; 1038 } 1039 1040 if (copy > length) 1041 copy = length; 1042 1043 if (!(rt->dst.dev->features&NETIF_F_SG)) { --- 30 unchanged lines hidden (view full) --- 1074 offset, copy, skb->len, skb) < 0) 1075 goto error_efault; 1076 1077 pfrag->offset += copy; 1078 skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy); 1079 skb->len += copy; 1080 skb->data_len += copy; 1081 skb->truesize += copy; | 1041 __skb_queue_tail(queue, skb); 1042 continue; 1043 } 1044 1045 if (copy > length) 1046 copy = length; 1047 1048 if (!(rt->dst.dev->features&NETIF_F_SG)) { --- 30 unchanged lines hidden (view full) --- 1079 offset, copy, skb->len, skb) < 0) 1080 goto error_efault; 1081 1082 pfrag->offset += copy; 1083 skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy); 1084 skb->len += copy; 1085 skb->data_len += copy; 1086 skb->truesize += copy; |
1082 refcount_add(copy, &sk->sk_wmem_alloc); | 1087 wmem_alloc_delta += copy; |
1083 } 1084 offset += copy; 1085 length -= copy; 1086 } 1087 | 1088 } 1089 offset += copy; 1090 length -= copy; 1091 } 1092 |
1093 refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc); |
|
1088 return 0; 1089 1090error_efault: 1091 err = -EFAULT; 1092error: 1093 cork->length -= length; 1094 IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTDISCARDS); | 1094 return 0; 1095 1096error_efault: 1097 err = -EFAULT; 1098error: 1099 cork->length -= length; 1100 IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTDISCARDS); |
1101 refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc); |
|
1095 return err; 1096} 1097 1098static int ip_setup_cork(struct sock *sk, struct inet_cork *cork, 1099 struct ipcm_cookie *ipc, struct rtable **rtp) 1100{ 1101 struct ip_options_rcu *opt; 1102 struct rtable *rt; --- 490 unchanged lines hidden --- | 1102 return err; 1103} 1104 1105static int ip_setup_cork(struct sock *sk, struct inet_cork *cork, 1106 struct ipcm_cookie *ipc, struct rtable **rtp) 1107{ 1108 struct ip_options_rcu *opt; 1109 struct rtable *rt; --- 490 unchanged lines hidden --- |