Skip to content

Commit

Permalink
rxrpc: Add tracepoint for working out where aborts happen
Browse files Browse the repository at this point in the history
Add a tracepoint for working out where local aborts happen.  Each
tracepoint call is labelled with a 3-letter code so that they can be
distinguished - and the DATA sequence number is added too where available.

rxrpc_kernel_abort_call() also takes a 3-letter code so that AFS can
indicate the circumstances when it aborts a call.

Signed-off-by: David Howells <[email protected]>
  • Loading branch information
dhowells committed Sep 7, 2016
1 parent e8d6bbb commit 5a42976
Show file tree
Hide file tree
Showing 11 changed files with 132 additions and 98 deletions.
17 changes: 10 additions & 7 deletions fs/afs/rxrpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp,
return wait_mode->wait(call);

error_do_abort:
rxrpc_kernel_abort_call(afs_socket, rxcall, RX_USER_ABORT);
rxrpc_kernel_abort_call(afs_socket, rxcall, RX_USER_ABORT, -ret, "KSD");
error_kill_call:
afs_end_call(call);
_leave(" = %d", ret);
Expand Down Expand Up @@ -425,12 +425,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);
abort_code, -ret, "KNC");
goto do_abort;
case -ENOTSUPP:
abort_code = RX_INVALID_OPERATION;
rxrpc_kernel_abort_call(afs_socket, call->rxcall,
abort_code);
abort_code, -ret, "KIV");
goto do_abort;
case -ENODATA:
case -EBADMSG:
Expand All @@ -440,7 +440,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);
abort_code, EBADMSG, "KUM");
goto do_abort;
}
}
Expand All @@ -463,6 +463,7 @@ static void afs_deliver_to_call(struct afs_call *call)
*/
static int afs_wait_for_call_to_complete(struct afs_call *call)
{
const char *abort_why;
int ret;

DECLARE_WAITQUEUE(myself, current);
Expand All @@ -481,9 +482,11 @@ static int afs_wait_for_call_to_complete(struct afs_call *call)
continue;
}

abort_why = "KWC";
ret = call->error;
if (call->state == AFS_CALL_COMPLETE)
break;
abort_why = "KWI";
ret = -EINTR;
if (signal_pending(current))
break;
Expand All @@ -497,7 +500,7 @@ static int afs_wait_for_call_to_complete(struct afs_call *call)
if (call->state < AFS_CALL_COMPLETE) {
_debug("call incomplete");
rxrpc_kernel_abort_call(afs_socket, call->rxcall,
RX_CALL_DEAD);
RX_CALL_DEAD, -ret, abort_why);
}

_debug("call complete");
Expand Down Expand Up @@ -695,7 +698,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);
RX_USER_ABORT, ENOMEM, "KOO");
default:
afs_end_call(call);
_leave(" [error]");
Expand Down Expand Up @@ -734,7 +737,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);
RX_USER_ABORT, ENOMEM, "KOO");
}
afs_end_call(call);
_leave(" [error]");
Expand Down
3 changes: 2 additions & 1 deletion include/net/af_rxrpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ 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 *, u32);
void rxrpc_kernel_abort_call(struct socket *, struct rxrpc_call *,
u32, int, const char *);
void rxrpc_kernel_end_call(struct socket *, struct rxrpc_call *);
struct rxrpc_call *rxrpc_kernel_accept_call(struct socket *, unsigned long,
rxrpc_notify_rx_t);
Expand Down
29 changes: 29 additions & 0 deletions include/trace/events/rxrpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,35 @@ TRACE_EVENT(rxrpc_skb,
__entry->where)
);

TRACE_EVENT(rxrpc_abort,
TP_PROTO(const char *why, u32 cid, u32 call_id, rxrpc_seq_t seq,
int abort_code, int error),

TP_ARGS(why, cid, call_id, seq, abort_code, error),

TP_STRUCT__entry(
__array(char, why, 4 )
__field(u32, cid )
__field(u32, call_id )
__field(rxrpc_seq_t, seq )
__field(int, abort_code )
__field(int, error )
),

TP_fast_assign(
memcpy(__entry->why, why, 4);
__entry->cid = cid;
__entry->call_id = call_id;
__entry->abort_code = abort_code;
__entry->error = error;
__entry->seq = seq;
),

TP_printk("%08x:%08x s=%u a=%d e=%d %s",
__entry->cid, __entry->call_id, __entry->seq,
__entry->abort_code, __entry->error, __entry->why)
);

#endif /* _TRACE_RXRPC_H */

/* This part must be outside protection */
Expand Down
14 changes: 9 additions & 5 deletions net/rxrpc/ar-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ struct rxrpc_security {
void *);

/* verify the security on a received packet */
int (*verify_packet)(struct rxrpc_call *, struct sk_buff *, u32 *);
int (*verify_packet)(struct rxrpc_call *, struct sk_buff *,
rxrpc_seq_t, u16);

/* issue a challenge */
int (*issue_challenge)(struct rxrpc_connection *);
Expand Down Expand Up @@ -637,9 +638,12 @@ static inline bool rxrpc_call_completed(struct rxrpc_call *call)
/*
* Record that a call is locally aborted.
*/
static inline bool __rxrpc_abort_call(struct rxrpc_call *call,
static inline bool __rxrpc_abort_call(const char *why, struct rxrpc_call *call,
rxrpc_seq_t seq,
u32 abort_code, int error)
{
trace_rxrpc_abort(why, call->cid, call->call_id, seq,
abort_code, error);
if (__rxrpc_set_call_completion(call,
RXRPC_CALL_LOCALLY_ABORTED,
abort_code, error)) {
Expand All @@ -649,13 +653,13 @@ static inline bool __rxrpc_abort_call(struct rxrpc_call *call,
return false;
}

static inline bool rxrpc_abort_call(struct rxrpc_call *call,
u32 abort_code, int error)
static inline bool rxrpc_abort_call(const char *why, struct rxrpc_call *call,
rxrpc_seq_t seq, u32 abort_code, int error)
{
bool ret;

write_lock_bh(&call->state_lock);
ret = __rxrpc_abort_call(call, abort_code, error);
ret = __rxrpc_abort_call(why, call, seq, abort_code, error);
write_unlock_bh(&call->state_lock);
return ret;
}
Expand Down
7 changes: 4 additions & 3 deletions net/rxrpc/call_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,8 @@ static int rxrpc_process_rx_queue(struct rxrpc_call *call,

/* secured packets must be verified and possibly decrypted */
if (call->conn->security->verify_packet(call, skb,
_abort_code) < 0)
sp->hdr.seq,
sp->hdr.cksum) < 0)
goto protocol_error;

rxrpc_insert_oos_packet(call, skb);
Expand Down Expand Up @@ -982,7 +983,7 @@ void rxrpc_process_call(struct work_struct *work)
}

if (test_bit(RXRPC_CALL_EV_LIFE_TIMER, &call->events)) {
rxrpc_abort_call(call, RX_CALL_TIMEOUT, ETIME);
rxrpc_abort_call("EXP", call, 0, RX_CALL_TIMEOUT, ETIME);

_debug("post timeout");
if (rxrpc_post_message(call, RXRPC_SKB_MARK_LOCAL_ERROR,
Expand All @@ -1005,7 +1006,7 @@ void rxrpc_process_call(struct work_struct *work)
case -EKEYEXPIRED:
case -EKEYREJECTED:
case -EPROTO:
rxrpc_abort_call(call, abort_code, -ret);
rxrpc_abort_call("PRO", call, 0, abort_code, -ret);
goto kill_ACKs;
}
}
Expand Down
2 changes: 1 addition & 1 deletion net/rxrpc/call_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ void rxrpc_release_call(struct rxrpc_sock *rx, struct rxrpc_call *call)

if (call->state < RXRPC_CALL_COMPLETE) {
_debug("+++ ABORTING STATE %d +++\n", call->state);
__rxrpc_abort_call(call, RX_CALL_DEAD, ECONNRESET);
__rxrpc_abort_call("SKT", call, 0, RX_CALL_DEAD, ECONNRESET);
clear_bit(RXRPC_CALL_EV_ACK_FINAL, &call->events);
rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ABORT);
}
Expand Down
6 changes: 6 additions & 0 deletions net/rxrpc/conn_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ static void rxrpc_abort_calls(struct rxrpc_connection *conn,
lockdep_is_held(&conn->channel_lock));
if (call) {
rxrpc_see_call(call);
if (compl == RXRPC_CALL_LOCALLY_ABORTED)
trace_rxrpc_abort("CON", call->cid,
call->call_id, 0,
abort_code, error);

write_lock_bh(&call->state_lock);
if (rxrpc_set_call_completion(call, compl, abort_code,
error)) {
Expand All @@ -167,6 +172,7 @@ static void rxrpc_abort_calls(struct rxrpc_connection *conn,
write_unlock_bh(&call->state_lock);
if (queue)
rxrpc_queue_call(call);

}
}

Expand Down
7 changes: 4 additions & 3 deletions net/rxrpc/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb)
_debug("protocol error");
write_lock_bh(&call->state_lock);
protocol_error_locked:
if (__rxrpc_abort_call(call, RX_PROTOCOL_ERROR, EPROTO))
if (__rxrpc_abort_call("FPR", call, 0, RX_PROTOCOL_ERROR, EPROTO))
rxrpc_queue_call(call);
free_packet_unlock:
write_unlock_bh(&call->state_lock);
Expand Down Expand Up @@ -495,9 +495,10 @@ static void rxrpc_process_jumbo_packet(struct rxrpc_call *call,
protocol_error:
_debug("protocol error");
rxrpc_free_skb(part);
rxrpc_free_skb(jumbo);
if (rxrpc_abort_call(call, RX_PROTOCOL_ERROR, EPROTO))
if (rxrpc_abort_call("PJP", call, sp->hdr.seq,
RX_PROTOCOL_ERROR, EPROTO))
rxrpc_queue_call(call);
rxrpc_free_skb(jumbo);
_leave("");
}

Expand Down
19 changes: 10 additions & 9 deletions net/rxrpc/insecure.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,32 @@ static int none_prime_packet_security(struct rxrpc_connection *conn)
}

static int none_secure_packet(struct rxrpc_call *call,
struct sk_buff *skb,
size_t data_size,
void *sechdr)
struct sk_buff *skb,
size_t data_size,
void *sechdr)
{
return 0;
}

static int none_verify_packet(struct rxrpc_call *call,
struct sk_buff *skb,
u32 *_abort_code)
struct sk_buff *skb,
rxrpc_seq_t seq,
u16 expected_cksum)
{
return 0;
}

static int none_respond_to_challenge(struct rxrpc_connection *conn,
struct sk_buff *skb,
u32 *_abort_code)
struct sk_buff *skb,
u32 *_abort_code)
{
*_abort_code = RX_PROTOCOL_ERROR;
return -EPROTO;
}

static int none_verify_response(struct rxrpc_connection *conn,
struct sk_buff *skb,
u32 *_abort_code)
struct sk_buff *skb,
u32 *_abort_code)
{
*_abort_code = RX_PROTOCOL_ERROR;
return -EPROTO;
Expand Down
Loading

0 comments on commit 5a42976

Please sign in to comment.