Skip to content

Commit

Permalink
Merge tag 'rxrpc-rewrite-20170406' of git://git.kernel.org/pub/scm/li…
Browse files Browse the repository at this point in the history
…nux/kernel/git/dhowells/linux-fs

David Howells says:

====================
rxrpc: Miscellany

Here's a set of patches that make some minor changes to AF_RXRPC:

 (1) Store error codes in struct rxrpc_call::error as negative codes and
     only convert to positive in recvmsg() to avoid confusion inside the
     kernel.

 (2) Note the result of trying to abort a call (this fails if the call is
     already 'completed').

 (3) Don't abort on temporary errors whilst processing challenge and
     response packets, but rather drop the packet and wait for
     retransmission.

And also adds some more tracing:

 (4) Protocol errors.

 (5) Received abort packets.

 (6) Changes in the Rx window size due to ACK packet information.

 (7) Client call initiation (to allow the rxrpc_call struct pointer, the
     wire call ID and the user ID/afs_call pointer to be cross-referenced).
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Apr 6, 2017
2 parents b404127 + 89ca694 commit ec1af27
Show file tree
Hide file tree
Showing 15 changed files with 294 additions and 108 deletions.
12 changes: 6 additions & 6 deletions fs/afs/rxrpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp,
call->state = AFS_CALL_COMPLETE;
if (ret != -ECONNABORTED) {
rxrpc_kernel_abort_call(afs_socket, rxcall, RX_USER_ABORT,
-ret, "KSD");
ret, "KSD");
} else {
abort_code = 0;
offset = 0;
Expand Down Expand Up @@ -478,12 +478,12 @@ static void afs_deliver_to_call(struct afs_call *call)
case -ENOTCONN:
abort_code = RX_CALL_DEAD;
rxrpc_kernel_abort_call(afs_socket, call->rxcall,
abort_code, -ret, "KNC");
abort_code, ret, "KNC");
goto save_error;
case -ENOTSUPP:
abort_code = RXGEN_OPCODE;
rxrpc_kernel_abort_call(afs_socket, call->rxcall,
abort_code, -ret, "KIV");
abort_code, ret, "KIV");
goto save_error;
case -ENODATA:
case -EBADMSG:
Expand All @@ -493,7 +493,7 @@ static void afs_deliver_to_call(struct afs_call *call)
if (call->state != AFS_CALL_AWAIT_REPLY)
abort_code = RXGEN_SS_UNMARSHAL;
rxrpc_kernel_abort_call(afs_socket, call->rxcall,
abort_code, EBADMSG, "KUM");
abort_code, -EBADMSG, "KUM");
goto save_error;
}
}
Expand Down Expand Up @@ -754,7 +754,7 @@ void afs_send_empty_reply(struct afs_call *call)
case -ENOMEM:
_debug("oom");
rxrpc_kernel_abort_call(afs_socket, call->rxcall,
RX_USER_ABORT, ENOMEM, "KOO");
RX_USER_ABORT, -ENOMEM, "KOO");
default:
_leave(" [error]");
return;
Expand Down Expand Up @@ -792,7 +792,7 @@ void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len)
if (n == -ENOMEM) {
_debug("oom");
rxrpc_kernel_abort_call(afs_socket, call->rxcall,
RX_USER_ABORT, ENOMEM, "KOO");
RX_USER_ABORT, -ENOMEM, "KOO");
}
_leave(" [error]");
}
Expand Down
2 changes: 1 addition & 1 deletion include/net/af_rxrpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ int rxrpc_kernel_send_data(struct socket *, struct rxrpc_call *,
struct msghdr *, size_t);
int rxrpc_kernel_recv_data(struct socket *, struct rxrpc_call *,
void *, size_t, size_t *, bool, u32 *);
void rxrpc_kernel_abort_call(struct socket *, struct rxrpc_call *,
bool rxrpc_kernel_abort_call(struct socket *, struct rxrpc_call *,
u32, int, const char *);
void rxrpc_kernel_end_call(struct socket *, struct rxrpc_call *);
void rxrpc_kernel_get_peer(struct socket *, struct rxrpc_call *,
Expand Down
101 changes: 101 additions & 0 deletions include/trace/events/rxrpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,57 @@ TRACE_EVENT(rxrpc_rx_ack,
__entry->n_acks)
);

TRACE_EVENT(rxrpc_rx_abort,
TP_PROTO(struct rxrpc_call *call, rxrpc_serial_t serial,
u32 abort_code),

TP_ARGS(call, serial, abort_code),

TP_STRUCT__entry(
__field(struct rxrpc_call *, call )
__field(rxrpc_serial_t, serial )
__field(u32, abort_code )
),

TP_fast_assign(
__entry->call = call;
__entry->serial = serial;
__entry->abort_code = abort_code;
),

TP_printk("c=%p ABORT %08x ac=%d",
__entry->call,
__entry->serial,
__entry->abort_code)
);

TRACE_EVENT(rxrpc_rx_rwind_change,
TP_PROTO(struct rxrpc_call *call, rxrpc_serial_t serial,
u32 rwind, bool wake),

TP_ARGS(call, serial, rwind, wake),

TP_STRUCT__entry(
__field(struct rxrpc_call *, call )
__field(rxrpc_serial_t, serial )
__field(u32, rwind )
__field(bool, wake )
),

TP_fast_assign(
__entry->call = call;
__entry->serial = serial;
__entry->rwind = rwind;
__entry->wake = wake;
),

TP_printk("c=%p %08x rw=%u%s",
__entry->call,
__entry->serial,
__entry->rwind,
__entry->wake ? " wake" : "")
);

TRACE_EVENT(rxrpc_tx_data,
TP_PROTO(struct rxrpc_call *call, rxrpc_seq_t seq,
rxrpc_serial_t serial, u8 flags, bool retrans, bool lose),
Expand Down Expand Up @@ -1087,6 +1138,56 @@ TRACE_EVENT(rxrpc_improper_term,
__entry->abort_code)
);

TRACE_EVENT(rxrpc_rx_eproto,
TP_PROTO(struct rxrpc_call *call, rxrpc_serial_t serial,
const char *why),

TP_ARGS(call, serial, why),

TP_STRUCT__entry(
__field(struct rxrpc_call *, call )
__field(rxrpc_serial_t, serial )
__field(const char *, why )
),

TP_fast_assign(
__entry->call = call;
__entry->serial = serial;
__entry->why = why;
),

TP_printk("c=%p EPROTO %08x %s",
__entry->call,
__entry->serial,
__entry->why)
);

TRACE_EVENT(rxrpc_connect_call,
TP_PROTO(struct rxrpc_call *call),

TP_ARGS(call),

TP_STRUCT__entry(
__field(struct rxrpc_call *, call )
__field(unsigned long, user_call_ID )
__field(u32, cid )
__field(u32, call_id )
),

TP_fast_assign(
__entry->call = call;
__entry->user_call_ID = call->user_call_ID;
__entry->cid = call->cid;
__entry->call_id = call->call_id;
),

TP_printk("c=%p u=%p %08x:%08x",
__entry->call,
(void *)__entry->user_call_ID,
__entry->cid,
__entry->call_id)
);

#endif /* _TRACE_RXRPC_H */

/* This part must be outside protection */
Expand Down
19 changes: 19 additions & 0 deletions net/rxrpc/ar-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,25 @@ static inline bool rxrpc_abort_call(const char *why, struct rxrpc_call *call,
return ret;
}

/*
* Abort a call due to a protocol error.
*/
static inline bool __rxrpc_abort_eproto(struct rxrpc_call *call,
struct sk_buff *skb,
const char *eproto_why,
const char *why,
u32 abort_code)
{
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);

trace_rxrpc_rx_eproto(call, sp->hdr.serial, eproto_why);
return rxrpc_abort_call(why, call, sp->hdr.seq, abort_code, -EPROTO);
}

#define rxrpc_abort_eproto(call, skb, eproto_why, abort_why, abort_code) \
__rxrpc_abort_eproto((call), (skb), tracepoint_string(eproto_why), \
(abort_why), (abort_code))

/*
* conn_client.c
*/
Expand Down
6 changes: 3 additions & 3 deletions net/rxrpc/call_accept.c
Original file line number Diff line number Diff line change
Expand Up @@ -413,11 +413,11 @@ struct rxrpc_call *rxrpc_new_incoming_call(struct rxrpc_local *local,

case RXRPC_CONN_REMOTELY_ABORTED:
rxrpc_set_call_completion(call, RXRPC_CALL_REMOTELY_ABORTED,
conn->remote_abort, ECONNABORTED);
conn->remote_abort, -ECONNABORTED);
break;
case RXRPC_CONN_LOCALLY_ABORTED:
rxrpc_abort_call("CON", call, sp->hdr.seq,
conn->local_abort, ECONNABORTED);
conn->local_abort, -ECONNABORTED);
break;
default:
BUG();
Expand Down Expand Up @@ -600,7 +600,7 @@ int rxrpc_reject_call(struct rxrpc_sock *rx)
write_lock_bh(&call->state_lock);
switch (call->state) {
case RXRPC_CALL_SERVER_ACCEPTING:
__rxrpc_abort_call("REJ", call, 1, RX_USER_ABORT, ECONNABORTED);
__rxrpc_abort_call("REJ", call, 1, RX_USER_ABORT, -ECONNABORTED);
abort = true;
/* fall through */
case RXRPC_CALL_COMPLETE:
Expand Down
2 changes: 1 addition & 1 deletion net/rxrpc/call_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ void rxrpc_process_call(struct work_struct *work)

now = ktime_get_real();
if (ktime_before(call->expire_at, now)) {
rxrpc_abort_call("EXP", call, 0, RX_CALL_TIMEOUT, ETIME);
rxrpc_abort_call("EXP", call, 0, RX_CALL_TIMEOUT, -ETIME);
set_bit(RXRPC_CALL_EV_ABORT, &call->events);
goto recheck_state;
}
Expand Down
4 changes: 2 additions & 2 deletions net/rxrpc/call_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -486,15 +486,15 @@ void rxrpc_release_calls_on_socket(struct rxrpc_sock *rx)
call = list_entry(rx->to_be_accepted.next,
struct rxrpc_call, accept_link);
list_del(&call->accept_link);
rxrpc_abort_call("SKR", call, 0, RX_CALL_DEAD, ECONNRESET);
rxrpc_abort_call("SKR", call, 0, RX_CALL_DEAD, -ECONNRESET);
rxrpc_put_call(call, rxrpc_call_put);
}

while (!list_empty(&rx->sock_calls)) {
call = list_entry(rx->sock_calls.next,
struct rxrpc_call, sock_link);
rxrpc_get_call(call, rxrpc_call_got);
rxrpc_abort_call("SKT", call, 0, RX_CALL_DEAD, ECONNRESET);
rxrpc_abort_call("SKT", call, 0, RX_CALL_DEAD, -ECONNRESET);
rxrpc_send_abort_packet(call);
rxrpc_release_call(rx, call);
rxrpc_put_call(call, rxrpc_call_put);
Expand Down
1 change: 1 addition & 0 deletions net/rxrpc/conn_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,7 @@ static void rxrpc_activate_one_channel(struct rxrpc_connection *conn,
call->cid = conn->proto.cid | channel;
call->call_id = call_id;

trace_rxrpc_connect_call(call);
_net("CONNECT call %08x:%08x as call %d on conn %d",
call->cid, call->call_id, call->debug_id, conn->debug_id);

Expand Down
17 changes: 10 additions & 7 deletions net/rxrpc/conn_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ static void rxrpc_abort_calls(struct rxrpc_connection *conn,
* generate a connection-level abort
*/
static int rxrpc_abort_connection(struct rxrpc_connection *conn,
u32 error, u32 abort_code)
int error, u32 abort_code)
{
struct rxrpc_wire_header whdr;
struct msghdr msg;
Expand Down Expand Up @@ -281,14 +281,17 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,

case RXRPC_PACKET_TYPE_ABORT:
if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header),
&wtmp, sizeof(wtmp)) < 0)
&wtmp, sizeof(wtmp)) < 0) {
trace_rxrpc_rx_eproto(NULL, sp->hdr.serial,
tracepoint_string("bad_abort"));
return -EPROTO;
}
abort_code = ntohl(wtmp);
_proto("Rx ABORT %%%u { ac=%d }", sp->hdr.serial, abort_code);

conn->state = RXRPC_CONN_REMOTELY_ABORTED;
rxrpc_abort_calls(conn, RXRPC_CALL_REMOTELY_ABORTED,
abort_code, ECONNABORTED);
abort_code, -ECONNABORTED);
return -ECONNABORTED;

case RXRPC_PACKET_TYPE_CHALLENGE:
Expand Down Expand Up @@ -327,7 +330,8 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,
return 0;

default:
_leave(" = -EPROTO [%u]", sp->hdr.type);
trace_rxrpc_rx_eproto(NULL, sp->hdr.serial,
tracepoint_string("bad_conn_pkt"));
return -EPROTO;
}
}
Expand Down Expand Up @@ -370,7 +374,7 @@ static void rxrpc_secure_connection(struct rxrpc_connection *conn)

abort:
_debug("abort %d, %d", ret, abort_code);
rxrpc_abort_connection(conn, -ret, abort_code);
rxrpc_abort_connection(conn, ret, abort_code);
_leave(" [aborted]");
}

Expand Down Expand Up @@ -419,9 +423,8 @@ void rxrpc_process_connection(struct work_struct *work)
goto out;

protocol_error:
if (rxrpc_abort_connection(conn, -ret, abort_code) < 0)
if (rxrpc_abort_connection(conn, ret, abort_code) < 0)
goto requeue_and_leave;
rxrpc_free_skb(skb, rxrpc_skb_rx_freed);
_leave(" [EPROTO]");
goto out;
}
17 changes: 12 additions & 5 deletions net/rxrpc/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
static void rxrpc_proto_abort(const char *why,
struct rxrpc_call *call, rxrpc_seq_t seq)
{
if (rxrpc_abort_call(why, call, seq, RX_PROTOCOL_ERROR, EBADMSG)) {
if (rxrpc_abort_call(why, call, seq, RX_PROTOCOL_ERROR, -EBADMSG)) {
set_bit(RXRPC_CALL_EV_ABORT, &call->events);
rxrpc_queue_call(call);
}
Expand Down Expand Up @@ -665,6 +665,8 @@ static void rxrpc_input_ackinfo(struct rxrpc_call *call, struct sk_buff *skb,
rwind = RXRPC_RXTX_BUFF_SIZE - 1;
if (rwind > call->tx_winsize)
wake = true;
trace_rxrpc_rx_rwind_change(call, sp->hdr.serial,
ntohl(ackinfo->rwind), wake);
call->tx_winsize = rwind;
}

Expand Down Expand Up @@ -877,7 +879,7 @@ static void rxrpc_input_ackall(struct rxrpc_call *call, struct sk_buff *skb)
}

/*
* Process an ABORT packet.
* Process an ABORT packet directed at a call.
*/
static void rxrpc_input_abort(struct rxrpc_call *call, struct sk_buff *skb)
{
Expand All @@ -892,10 +894,12 @@ static void rxrpc_input_abort(struct rxrpc_call *call, struct sk_buff *skb)
&wtmp, sizeof(wtmp)) >= 0)
abort_code = ntohl(wtmp);

trace_rxrpc_rx_abort(call, sp->hdr.serial, abort_code);

_proto("Rx ABORT %%%u { %x }", sp->hdr.serial, abort_code);

if (rxrpc_set_call_completion(call, RXRPC_CALL_REMOTELY_ABORTED,
abort_code, ECONNABORTED))
abort_code, -ECONNABORTED))
rxrpc_notify_socket(call);
}

Expand Down Expand Up @@ -958,7 +962,7 @@ static void rxrpc_input_implicit_end_call(struct rxrpc_connection *conn,
case RXRPC_CALL_COMPLETE:
break;
default:
if (rxrpc_abort_call("IMP", call, 0, RX_CALL_DEAD, ESHUTDOWN)) {
if (rxrpc_abort_call("IMP", call, 0, RX_CALL_DEAD, -ESHUTDOWN)) {
set_bit(RXRPC_CALL_EV_ABORT, &call->events);
rxrpc_queue_call(call);
}
Expand Down Expand Up @@ -1017,8 +1021,11 @@ int rxrpc_extract_header(struct rxrpc_skb_priv *sp, struct sk_buff *skb)
struct rxrpc_wire_header whdr;

/* dig out the RxRPC connection details */
if (skb_copy_bits(skb, 0, &whdr, sizeof(whdr)) < 0)
if (skb_copy_bits(skb, 0, &whdr, sizeof(whdr)) < 0) {
trace_rxrpc_rx_eproto(NULL, sp->hdr.serial,
tracepoint_string("bad_hdr"));
return -EBADMSG;
}

memset(sp, 0, sizeof(*sp));
sp->hdr.epoch = ntohl(whdr.epoch);
Expand Down
Loading

0 comments on commit ec1af27

Please sign in to comment.