summaryrefslogtreecommitdiff
path: root/net/rxrpc/ar-call.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2016-03-04 15:53:46 +0000
committerDavid Howells <dhowells@redhat.com>2016-03-04 15:53:46 +0000
commit0d12f8a4027d021c9cc942f09f38d28288020c5d (patch)
tree751f54f93f15d9c0146cf2e4243dbfc25fd1cc6d /net/rxrpc/ar-call.c
parent4c198ad17a7253cc8ef3ff39bfe73d6b5e65ceef (diff)
downloadlinux-0d12f8a4027d021c9cc942f09f38d28288020c5d.tar.gz
rxrpc: Keep the skb private record of the Rx header in host byte order
Currently, a copy of the Rx packet header is copied into the the sk_buff private data so that we can advance the pointer into the buffer, potentially discarding the original. At the moment, this copy is held in network byte order, but this means we're doing a lot of unnecessary translations. The reasons it was done this way are that we need the values in network byte order occasionally and we can use the copy, slightly modified, as part of an iov array when sending an ack or an abort packet. However, it seems more reasonable on review that it would be better kept in host byte order and that we make up a new header when we want to send another packet. To this end, rename the original header struct to rxrpc_wire_header (with BE fields) and institute a variant called rxrpc_host_header that has host order fields. Change the struct in the sk_buff private data into an rxrpc_host_header and translate the values when filling it in. This further allows us to keep values kept in various structures in host byte order rather than network byte order and allows removal of some fields that are byteswapped duplicates. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'net/rxrpc/ar-call.c')
-rw-r--r--net/rxrpc/ar-call.c68
1 files changed, 32 insertions, 36 deletions
diff --git a/net/rxrpc/ar-call.c b/net/rxrpc/ar-call.c
index 3468a0705ab7..4a499e0100f1 100644
--- a/net/rxrpc/ar-call.c
+++ b/net/rxrpc/ar-call.c
@@ -64,11 +64,11 @@ static DEFINE_HASHTABLE(rxrpc_call_hash, 10);
* Hash function for rxrpc_call_hash
*/
static unsigned long rxrpc_call_hashfunc(
- u8 clientflag,
- __be32 cid,
- __be32 call_id,
- __be32 epoch,
- __be16 service_id,
+ u8 in_clientflag,
+ u32 cid,
+ u32 call_id,
+ u32 epoch,
+ u16 service_id,
sa_family_t proto,
void *localptr,
unsigned int addr_size,
@@ -77,7 +77,6 @@ static unsigned long rxrpc_call_hashfunc(
const u16 *p;
unsigned int i;
unsigned long key;
- u32 hcid = ntohl(cid);
_enter("");
@@ -85,12 +84,12 @@ static unsigned long rxrpc_call_hashfunc(
/* We just want to add up the __be32 values, so forcing the
* cast should be okay.
*/
- key += (__force u32)epoch;
- key += (__force u16)service_id;
- key += (__force u32)call_id;
- key += (hcid & RXRPC_CIDMASK) >> RXRPC_CIDSHIFT;
- key += hcid & RXRPC_CHANNELMASK;
- key += clientflag;
+ key += epoch;
+ key += service_id;
+ key += call_id;
+ key += (cid & RXRPC_CIDMASK) >> RXRPC_CIDSHIFT;
+ key += cid & RXRPC_CHANNELMASK;
+ key += in_clientflag;
key += proto;
/* Step through the peer address in 16-bit portions for speed */
for (i = 0, p = (const u16 *)peer_addr; i < addr_size >> 1; i++, p++)
@@ -148,19 +147,16 @@ static void rxrpc_call_hash_del(struct rxrpc_call *call)
* isn't there.
*/
struct rxrpc_call *rxrpc_find_call_hash(
- u8 clientflag,
- __be32 cid,
- __be32 call_id,
- __be32 epoch,
- __be16 service_id,
+ struct rxrpc_host_header *hdr,
void *localptr,
sa_family_t proto,
- const u8 *peer_addr)
+ const void *peer_addr)
{
unsigned long key;
unsigned int addr_size = 0;
struct rxrpc_call *call = NULL;
struct rxrpc_call *ret = NULL;
+ u8 in_clientflag = hdr->flags & RXRPC_CLIENT_INITIATED;
_enter("");
switch (proto) {
@@ -174,20 +170,21 @@ struct rxrpc_call *rxrpc_find_call_hash(
break;
}
- key = rxrpc_call_hashfunc(clientflag, cid, call_id, epoch,
- service_id, proto, localptr, addr_size,
+ key = rxrpc_call_hashfunc(in_clientflag, hdr->cid, hdr->callNumber,
+ hdr->epoch, hdr->serviceId,
+ proto, localptr, addr_size,
peer_addr);
hash_for_each_possible_rcu(rxrpc_call_hash, call, hash_node, key) {
if (call->hash_key == key &&
- call->call_id == call_id &&
- call->cid == cid &&
- call->in_clientflag == clientflag &&
- call->service_id == service_id &&
+ call->call_id == hdr->callNumber &&
+ call->cid == hdr->cid &&
+ call->in_clientflag == in_clientflag &&
+ call->service_id == hdr->serviceId &&
call->proto == proto &&
call->local == localptr &&
memcmp(call->peer_ip.ipv6_addr, peer_addr,
- addr_size) == 0 &&
- call->epoch == epoch) {
+ addr_size) == 0 &&
+ call->epoch == hdr->epoch) {
ret = call;
break;
}
@@ -414,12 +411,12 @@ found_extant_second:
*/
struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *rx,
struct rxrpc_connection *conn,
- struct rxrpc_header *hdr,
+ struct rxrpc_host_header *hdr,
gfp_t gfp)
{
struct rxrpc_call *call, *candidate;
struct rb_node **p, *parent;
- __be32 call_id;
+ u32 call_id;
_enter(",%d,,%x", conn->debug_id, gfp);
@@ -433,7 +430,7 @@ struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *rx,
candidate->conn = conn;
candidate->cid = hdr->cid;
candidate->call_id = hdr->callNumber;
- candidate->channel = ntohl(hdr->cid) & RXRPC_CHANNELMASK;
+ candidate->channel = hdr->cid & RXRPC_CHANNELMASK;
candidate->rx_data_post = 0;
candidate->state = RXRPC_CALL_SERVER_ACCEPTING;
if (conn->security_ix > 0)
@@ -492,9 +489,9 @@ struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *rx,
/* The tree is sorted in order of the __be32 value without
* turning it into host order.
*/
- if ((__force u32)call_id < (__force u32)call->call_id)
+ if (call_id < call->call_id)
p = &(*p)->rb_left;
- else if ((__force u32)call_id > (__force u32)call->call_id)
+ else if (call_id > call->call_id)
p = &(*p)->rb_right;
else
goto old_call;
@@ -714,8 +711,7 @@ void rxrpc_release_call(struct rxrpc_call *call)
_debug("- zap %s %%%u #%u",
rxrpc_pkts[sp->hdr.type],
- ntohl(sp->hdr.serial),
- ntohl(sp->hdr.seq));
+ sp->hdr.serial, sp->hdr.seq);
rxrpc_free_skb(skb);
spin_lock_bh(&call->lock);
}
@@ -873,9 +869,9 @@ static void rxrpc_cleanup_call(struct rxrpc_call *call)
unsigned long _skb;
_skb = call->acks_window[call->acks_tail] & ~1;
- sp = rxrpc_skb((struct sk_buff *) _skb);
- _debug("+++ clear Tx %u", ntohl(sp->hdr.seq));
- rxrpc_free_skb((struct sk_buff *) _skb);
+ sp = rxrpc_skb((struct sk_buff *)_skb);
+ _debug("+++ clear Tx %u", sp->hdr.seq);
+ rxrpc_free_skb((struct sk_buff *)_skb);
call->acks_tail =
(call->acks_tail + 1) & (call->acks_winsz - 1);
}