diff options
author | Rémi Denis-Courmont <remi.denis-courmont@nokia.com> | 2010-01-03 21:02:48 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-01-07 03:24:55 -0500 |
commit | fea93ecef619b5779ca6984568517b1685079b05 (patch) | |
tree | 9894ba0ea3f8f4a1191697fecb0f63a45767a90f /net | |
parent | fc6a110754476362f9f4fa3199a637f2331c5993 (diff) |
Phonet: zero-copy GPRS TX
Send aligned pipe payload if requested to do so. Then, the socket buffer
needs not be fragmented anymore.
Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/phonet/pep.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/net/phonet/pep.c b/net/phonet/pep.c index e23e30907d34..72db27e3fc06 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c | |||
@@ -444,6 +444,7 @@ static int pep_connreq_rcv(struct sock *sk, struct sk_buff *skb) | |||
444 | struct sockaddr_pn dst; | 444 | struct sockaddr_pn dst; |
445 | u16 peer_type; | 445 | u16 peer_type; |
446 | u8 pipe_handle, enabled, n_sb; | 446 | u8 pipe_handle, enabled, n_sb; |
447 | u8 aligned = 0; | ||
447 | 448 | ||
448 | if (!pskb_pull(skb, sizeof(*hdr) + 4)) | 449 | if (!pskb_pull(skb, sizeof(*hdr) + 4)) |
449 | return -EINVAL; | 450 | return -EINVAL; |
@@ -482,6 +483,9 @@ static int pep_connreq_rcv(struct sock *sk, struct sk_buff *skb) | |||
482 | return -EINVAL; | 483 | return -EINVAL; |
483 | peer_type = (peer_type & 0xff00) | data[0]; | 484 | peer_type = (peer_type & 0xff00) | data[0]; |
484 | break; | 485 | break; |
486 | case PN_PIPE_SB_ALIGNED_DATA: | ||
487 | aligned = data[0] != 0; | ||
488 | break; | ||
485 | } | 489 | } |
486 | n_sb--; | 490 | n_sb--; |
487 | } | 491 | } |
@@ -513,6 +517,7 @@ static int pep_connreq_rcv(struct sock *sk, struct sk_buff *skb) | |||
513 | newpn->rx_credits = 0; | 517 | newpn->rx_credits = 0; |
514 | newpn->rx_fc = newpn->tx_fc = PN_LEGACY_FLOW_CONTROL; | 518 | newpn->rx_fc = newpn->tx_fc = PN_LEGACY_FLOW_CONTROL; |
515 | newpn->init_enable = enabled; | 519 | newpn->init_enable = enabled; |
520 | newpn->aligned = aligned; | ||
516 | 521 | ||
517 | BUG_ON(!skb_queue_empty(&newsk->sk_receive_queue)); | 522 | BUG_ON(!skb_queue_empty(&newsk->sk_receive_queue)); |
518 | skb_queue_head(&newsk->sk_receive_queue, skb); | 523 | skb_queue_head(&newsk->sk_receive_queue, skb); |
@@ -832,11 +837,15 @@ static int pipe_skb_send(struct sock *sk, struct sk_buff *skb) | |||
832 | return -ENOBUFS; | 837 | return -ENOBUFS; |
833 | } | 838 | } |
834 | 839 | ||
835 | skb_push(skb, 3); | 840 | skb_push(skb, 3 + pn->aligned); |
836 | skb_reset_transport_header(skb); | 841 | skb_reset_transport_header(skb); |
837 | ph = pnp_hdr(skb); | 842 | ph = pnp_hdr(skb); |
838 | ph->utid = 0; | 843 | ph->utid = 0; |
839 | ph->message_id = PNS_PIPE_DATA; | 844 | if (pn->aligned) { |
845 | ph->message_id = PNS_PIPE_ALIGNED_DATA; | ||
846 | ph->data[0] = 0; /* padding */ | ||
847 | } else | ||
848 | ph->message_id = PNS_PIPE_DATA; | ||
840 | ph->pipe_handle = pn->pipe_handle; | 849 | ph->pipe_handle = pn->pipe_handle; |
841 | 850 | ||
842 | return pn_skb_send(sk, skb, &pipe_srv); | 851 | return pn_skb_send(sk, skb, &pipe_srv); |
@@ -930,6 +939,9 @@ int pep_write(struct sock *sk, struct sk_buff *skb) | |||
930 | struct sk_buff *rskb, *fs; | 939 | struct sk_buff *rskb, *fs; |
931 | int flen = 0; | 940 | int flen = 0; |
932 | 941 | ||
942 | if (pep_sk(sk)->aligned) | ||
943 | return pipe_skb_send(sk, skb); | ||
944 | |||
933 | rskb = alloc_skb(MAX_PNPIPE_HEADER, GFP_ATOMIC); | 945 | rskb = alloc_skb(MAX_PNPIPE_HEADER, GFP_ATOMIC); |
934 | if (!rskb) { | 946 | if (!rskb) { |
935 | kfree_skb(skb); | 947 | kfree_skb(skb); |