[PATCH net-next 1/9] rxrpc: Don't store the rxrpc header in the Tx queue sk_buffs [ver #2]

2016-09-22 Thread David Howells
Don't store the rxrpc protocol header in sk_buffs on the transmit queue,
but rather generate it on the fly and pass it to kernel_sendmsg() as a
separate iov.  This reduces the amount of storage required.

Note that the security header is still stored in the sk_buff as it may get
encrypted along with the data (and doesn't change with each transmission).

Signed-off-by: David Howells 
---

 net/rxrpc/ar-internal.h |5 +--
 net/rxrpc/call_event.c  |   11 +-
 net/rxrpc/conn_object.c |1 -
 net/rxrpc/output.c  |   83 ---
 net/rxrpc/rxkad.c   |8 ++---
 net/rxrpc/sendmsg.c |   51 +
 6 files changed, 71 insertions(+), 88 deletions(-)

diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index 034f525f2235..f021df4a6a22 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -385,10 +385,9 @@ struct rxrpc_connection {
int debug_id;   /* debug ID for printks */
atomic_tserial; /* packet serial number counter 
*/
unsigned inthi_serial;  /* highest serial number 
received */
+   u32 security_nonce; /* response re-use preventer */
u8  size_align; /* data size alignment (for 
security) */
-   u8  header_size;/* rxrpc + security header size 
*/
u8  security_size;  /* security header size */
-   u32 security_nonce; /* response re-use preventer */
u8  security_ix;/* security type */
u8  out_clientflag; /* RXRPC_CLIENT_INITIATED if we 
are client */
 };
@@ -946,7 +945,7 @@ extern const s8 rxrpc_ack_priority[];
  * output.c
  */
 int rxrpc_send_call_packet(struct rxrpc_call *, u8);
-int rxrpc_send_data_packet(struct rxrpc_connection *, struct sk_buff *);
+int rxrpc_send_data_packet(struct rxrpc_call *, struct sk_buff *);
 void rxrpc_reject_packets(struct rxrpc_local *);
 
 /*
diff --git a/net/rxrpc/call_event.c b/net/rxrpc/call_event.c
index 7d1b99824ed9..6247ce25eb21 100644
--- a/net/rxrpc/call_event.c
+++ b/net/rxrpc/call_event.c
@@ -139,7 +139,6 @@ void rxrpc_propose_ACK(struct rxrpc_call *call, u8 
ack_reason,
  */
 static void rxrpc_resend(struct rxrpc_call *call)
 {
-   struct rxrpc_wire_header *whdr;
struct rxrpc_skb_priv *sp;
struct sk_buff *skb;
rxrpc_seq_t cursor, seq, top;
@@ -201,15 +200,8 @@ static void rxrpc_resend(struct rxrpc_call *call)
skb = call->rxtx_buffer[ix];
rxrpc_get_skb(skb, rxrpc_skb_tx_got);
spin_unlock_bh(&call->lock);
-   sp = rxrpc_skb(skb);
-
-   /* Each Tx packet needs a new serial number */
-   sp->hdr.serial = atomic_inc_return(&call->conn->serial);
 
-   whdr = (struct rxrpc_wire_header *)skb->head;
-   whdr->serial = htonl(sp->hdr.serial);
-
-   if (rxrpc_send_data_packet(call->conn, skb) < 0) {
+   if (rxrpc_send_data_packet(call, skb) < 0) {
call->resend_at = now + 2;
rxrpc_free_skb(skb, rxrpc_skb_tx_freed);
return;
@@ -217,6 +209,7 @@ static void rxrpc_resend(struct rxrpc_call *call)
 
if (rxrpc_is_client_call(call))
rxrpc_expose_client_call(call);
+   sp = rxrpc_skb(skb);
sp->resend_at = now + rxrpc_resend_timeout;
 
rxrpc_free_skb(skb, rxrpc_skb_tx_freed);
diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c
index 3b55aee0c436..e1e83af47866 100644
--- a/net/rxrpc/conn_object.c
+++ b/net/rxrpc/conn_object.c
@@ -53,7 +53,6 @@ struct rxrpc_connection *rxrpc_alloc_connection(gfp_t gfp)
spin_lock_init(&conn->state_lock);
conn->debug_id = atomic_inc_return(&rxrpc_debug_id);
conn->size_align = 4;
-   conn->header_size = sizeof(struct rxrpc_wire_header);
conn->idle_timestamp = jiffies;
}
 
diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
index 16e18a94ffa6..817fb0e82d6a 100644
--- a/net/rxrpc/output.c
+++ b/net/rxrpc/output.c
@@ -208,19 +208,42 @@ out:
 /*
  * send a packet through the transport endpoint
  */
-int rxrpc_send_data_packet(struct rxrpc_connection *conn, struct sk_buff *skb)
+int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb)
 {
-   struct kvec iov[1];
+   struct rxrpc_connection *conn = call->conn;
+   struct rxrpc_wire_header whdr;
+   struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
struct msghdr msg;
+   struct kvec iov[2];
+   rxrpc_serial_t serial;
+   size_t len;
int ret, opt;
 
_enter(",{%d}", skb->len);
 
-   iov[0].iov_base = skb->head;
-   iov[0].iov_len = skb->len;
+   /* Each transm

[PATCH net-next 1/9] rxrpc: Don't store the rxrpc header in the Tx queue sk_buffs

2016-09-21 Thread David Howells
Don't store the rxrpc protocol header in sk_buffs on the transmit queue,
but rather generate it on the fly and pass it to kernel_sendmsg() as a
separate iov.  This reduces the amount of storage required.

Note that the security header is still stored in the sk_buff as it may get
encrypted along with the data (and doesn't change with each transmission).

Signed-off-by: David Howells 
---

 net/rxrpc/ar-internal.h |5 +--
 net/rxrpc/call_event.c  |   11 +-
 net/rxrpc/conn_object.c |1 -
 net/rxrpc/output.c  |   83 ---
 net/rxrpc/rxkad.c   |8 ++---
 net/rxrpc/sendmsg.c |   51 +
 6 files changed, 71 insertions(+), 88 deletions(-)

diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index 034f525f2235..f021df4a6a22 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -385,10 +385,9 @@ struct rxrpc_connection {
int debug_id;   /* debug ID for printks */
atomic_tserial; /* packet serial number counter 
*/
unsigned inthi_serial;  /* highest serial number 
received */
+   u32 security_nonce; /* response re-use preventer */
u8  size_align; /* data size alignment (for 
security) */
-   u8  header_size;/* rxrpc + security header size 
*/
u8  security_size;  /* security header size */
-   u32 security_nonce; /* response re-use preventer */
u8  security_ix;/* security type */
u8  out_clientflag; /* RXRPC_CLIENT_INITIATED if we 
are client */
 };
@@ -946,7 +945,7 @@ extern const s8 rxrpc_ack_priority[];
  * output.c
  */
 int rxrpc_send_call_packet(struct rxrpc_call *, u8);
-int rxrpc_send_data_packet(struct rxrpc_connection *, struct sk_buff *);
+int rxrpc_send_data_packet(struct rxrpc_call *, struct sk_buff *);
 void rxrpc_reject_packets(struct rxrpc_local *);
 
 /*
diff --git a/net/rxrpc/call_event.c b/net/rxrpc/call_event.c
index 7d1b99824ed9..6247ce25eb21 100644
--- a/net/rxrpc/call_event.c
+++ b/net/rxrpc/call_event.c
@@ -139,7 +139,6 @@ void rxrpc_propose_ACK(struct rxrpc_call *call, u8 
ack_reason,
  */
 static void rxrpc_resend(struct rxrpc_call *call)
 {
-   struct rxrpc_wire_header *whdr;
struct rxrpc_skb_priv *sp;
struct sk_buff *skb;
rxrpc_seq_t cursor, seq, top;
@@ -201,15 +200,8 @@ static void rxrpc_resend(struct rxrpc_call *call)
skb = call->rxtx_buffer[ix];
rxrpc_get_skb(skb, rxrpc_skb_tx_got);
spin_unlock_bh(&call->lock);
-   sp = rxrpc_skb(skb);
-
-   /* Each Tx packet needs a new serial number */
-   sp->hdr.serial = atomic_inc_return(&call->conn->serial);
 
-   whdr = (struct rxrpc_wire_header *)skb->head;
-   whdr->serial = htonl(sp->hdr.serial);
-
-   if (rxrpc_send_data_packet(call->conn, skb) < 0) {
+   if (rxrpc_send_data_packet(call, skb) < 0) {
call->resend_at = now + 2;
rxrpc_free_skb(skb, rxrpc_skb_tx_freed);
return;
@@ -217,6 +209,7 @@ static void rxrpc_resend(struct rxrpc_call *call)
 
if (rxrpc_is_client_call(call))
rxrpc_expose_client_call(call);
+   sp = rxrpc_skb(skb);
sp->resend_at = now + rxrpc_resend_timeout;
 
rxrpc_free_skb(skb, rxrpc_skb_tx_freed);
diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c
index 3b55aee0c436..e1e83af47866 100644
--- a/net/rxrpc/conn_object.c
+++ b/net/rxrpc/conn_object.c
@@ -53,7 +53,6 @@ struct rxrpc_connection *rxrpc_alloc_connection(gfp_t gfp)
spin_lock_init(&conn->state_lock);
conn->debug_id = atomic_inc_return(&rxrpc_debug_id);
conn->size_align = 4;
-   conn->header_size = sizeof(struct rxrpc_wire_header);
conn->idle_timestamp = jiffies;
}
 
diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
index 16e18a94ffa6..817fb0e82d6a 100644
--- a/net/rxrpc/output.c
+++ b/net/rxrpc/output.c
@@ -208,19 +208,42 @@ out:
 /*
  * send a packet through the transport endpoint
  */
-int rxrpc_send_data_packet(struct rxrpc_connection *conn, struct sk_buff *skb)
+int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb)
 {
-   struct kvec iov[1];
+   struct rxrpc_connection *conn = call->conn;
+   struct rxrpc_wire_header whdr;
+   struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
struct msghdr msg;
+   struct kvec iov[2];
+   rxrpc_serial_t serial;
+   size_t len;
int ret, opt;
 
_enter(",{%d}", skb->len);
 
-   iov[0].iov_base = skb->head;
-   iov[0].iov_len = skb->len;
+   /* Each transm