#include <linux/tracepoint.h>
TRACE_EVENT(rxrpc_call,
- TP_PROTO(struct rxrpc_call *call, int op, int usage, int nskb,
+ TP_PROTO(struct rxrpc_call *call, enum rxrpc_call_trace op,
+ int usage, int nskb,
const void *where, const void *aux),
TP_ARGS(call, op, usage, nskb, where, aux),
TP_printk("c=%p %s u=%d s=%d p=%pSR a=%p",
__entry->call,
- (__entry->op == 0 ? "NWc" :
- __entry->op == 1 ? "NWs" :
- __entry->op == 2 ? "SEE" :
- __entry->op == 3 ? "GET" :
- __entry->op == 4 ? "Gsb" :
- __entry->op == 5 ? "PUT" :
- "Psb"),
+ rxrpc_call_traces[__entry->op],
__entry->usage,
__entry->nskb,
__entry->where,
_enter("%d{%d}", call->debug_id, atomic_read(&call->usage));
rxrpc_remove_user_ID(rxrpc_sk(sock->sk), call);
rxrpc_purge_queue(&call->knlrecv_queue);
- rxrpc_put_call(call);
+ rxrpc_put_call(call, rxrpc_call_put);
}
EXPORT_SYMBOL(rxrpc_kernel_end_call);
unsigned long ackr_window[RXRPC_ACKR_WINDOW_ASZ + 1];
};
+enum rxrpc_call_trace {
+ rxrpc_call_new_client,
+ rxrpc_call_new_service,
+ rxrpc_call_queued,
+ rxrpc_call_queued_ref,
+ rxrpc_call_seen,
+ rxrpc_call_got,
+ rxrpc_call_got_skb,
+ rxrpc_call_got_userid,
+ rxrpc_call_put,
+ rxrpc_call_put_skb,
+ rxrpc_call_put_userid,
+ rxrpc_call_put_noqueue,
+ rxrpc_call__nr_trace
+};
+
+extern const char rxrpc_call_traces[rxrpc_call__nr_trace][4];
+
#include <trace/events/rxrpc.h>
/*
void rxrpc_release_call(struct rxrpc_call *);
void rxrpc_release_calls_on_socket(struct rxrpc_sock *);
void rxrpc_see_call(struct rxrpc_call *);
-void rxrpc_get_call(struct rxrpc_call *);
-void rxrpc_put_call(struct rxrpc_call *);
+void rxrpc_get_call(struct rxrpc_call *, enum rxrpc_call_trace);
+void rxrpc_put_call(struct rxrpc_call *, enum rxrpc_call_trace);
void rxrpc_get_call_for_skb(struct rxrpc_call *, struct sk_buff *);
void rxrpc_put_call_for_skb(struct rxrpc_call *, struct sk_buff *);
void __exit rxrpc_destroy_all_calls(void);
write_lock(&rx->call_lock);
if (!test_and_set_bit(RXRPC_CALL_INIT_ACCEPT, &call->flags)) {
- rxrpc_get_call(call);
+ rxrpc_get_call(call, rxrpc_call_got);
spin_lock(&call->conn->state_lock);
if (sp->hdr.securityIndex > 0 &&
_debug("done");
read_unlock_bh(&local->services_lock);
rxrpc_free_skb(notification);
- rxrpc_put_call(call);
+ rxrpc_put_call(call, rxrpc_call_put);
_leave(" = 0");
return 0;
read_lock_bh(&call->state_lock);
if (!test_bit(RXRPC_CALL_RELEASED, &call->flags) &&
!test_and_set_bit(RXRPC_CALL_EV_RELEASE, &call->events)) {
- rxrpc_get_call(call);
+ rxrpc_get_call(call, rxrpc_call_got);
rxrpc_queue_call(call);
}
read_unlock_bh(&call->state_lock);
- rxrpc_put_call(call);
+ rxrpc_put_call(call, rxrpc_call_put);
ret = -ECONNREFUSED;
error:
rxrpc_free_skb(notification);
}
/* formalise the acceptance */
+ rxrpc_get_call(call, rxrpc_call_got_userid);
call->notify_rx = notify_rx;
call->user_call_ID = user_call_ID;
rb_link_node(&call->sock_node, parent, pp);
BUG();
rxrpc_queue_call(call);
- rxrpc_get_call(call);
write_unlock_bh(&call->state_lock);
write_unlock(&rx->call_lock);
_leave(" = %p{%d}", call, call->debug_id);
kill_ACKs:
del_timer_sync(&call->ack_timer);
if (test_and_clear_bit(RXRPC_CALL_EV_ACK_FINAL, &call->events))
- rxrpc_put_call(call);
+ rxrpc_put_call(call, rxrpc_call_put);
clear_bit(RXRPC_CALL_EV_ACK, &call->events);
maybe_reschedule:
[RXRPC_CALL_NETWORK_ERROR] = "NetError",
};
+const char rxrpc_call_traces[rxrpc_call__nr_trace][4] = {
+ [rxrpc_call_new_client] = "NWc",
+ [rxrpc_call_new_service] = "NWs",
+ [rxrpc_call_queued] = "QUE",
+ [rxrpc_call_queued_ref] = "QUR",
+ [rxrpc_call_seen] = "SEE",
+ [rxrpc_call_got] = "GOT",
+ [rxrpc_call_got_skb] = "Gsk",
+ [rxrpc_call_got_userid] = "Gus",
+ [rxrpc_call_put] = "PUT",
+ [rxrpc_call_put_skb] = "Psk",
+ [rxrpc_call_put_userid] = "Pus",
+ [rxrpc_call_put_noqueue] = "PNQ",
+};
+
struct kmem_cache *rxrpc_call_jar;
LIST_HEAD(rxrpc_calls);
DEFINE_RWLOCK(rxrpc_call_lock);
return NULL;
found_extant_call:
- rxrpc_get_call(call);
+ rxrpc_get_call(call, rxrpc_call_got);
read_unlock(&rx->call_lock);
_leave(" = %p [%d]", call, atomic_read(&call->usage));
return call;
goto found_user_ID_now_present;
}
- rxrpc_get_call(call);
-
+ rxrpc_get_call(call, rxrpc_call_got_userid);
rb_link_node(&call->sock_node, parent, pp);
rb_insert_color(&call->sock_node, &rx->calls);
write_unlock(&rx->call_lock);
write_lock(&rx->call_lock);
rb_erase(&call->sock_node, &rx->calls);
write_unlock(&rx->call_lock);
- rxrpc_put_call(call);
+ rxrpc_put_call(call, rxrpc_call_put_userid);
write_lock_bh(&rxrpc_call_lock);
list_del_init(&call->link);
set_bit(RXRPC_CALL_RELEASED, &call->flags);
call->state = RXRPC_CALL_DEAD;
- rxrpc_put_call(call);
+ rxrpc_put_call(call, rxrpc_call_put);
_leave(" = %d", ret);
return ERR_PTR(ret);
write_unlock(&rx->call_lock);
set_bit(RXRPC_CALL_RELEASED, &call->flags);
call->state = RXRPC_CALL_DEAD;
- rxrpc_put_call(call);
+ rxrpc_put_call(call, rxrpc_call_put);
_leave(" = -EEXIST [%p]", call);
return ERR_PTR(-EEXIST);
}
if (!candidate)
return ERR_PTR(-EBUSY);
- trace_rxrpc_call(candidate, 1, atomic_read(&candidate->usage),
- 0, here, NULL);
+ trace_rxrpc_call(candidate, rxrpc_call_new_service,
+ atomic_read(&candidate->usage), 0, here, NULL);
chan = sp->hdr.cid & RXRPC_CHANNELMASK;
candidate->socket = rx;
read_unlock(&call->state_lock);
goto aborted_call;
default:
- rxrpc_get_call(call);
+ rxrpc_get_call(call, rxrpc_call_got);
read_unlock(&call->state_lock);
goto extant_call;
}
int n = atomic_read(&call->usage);
int m = atomic_read(&call->skb_count);
- trace_rxrpc_call(call, 2, n, m, here, 0);
+ trace_rxrpc_call(call, rxrpc_call_seen, n, m, here, NULL);
}
}
/*
* Note the addition of a ref on a call.
*/
-void rxrpc_get_call(struct rxrpc_call *call)
+void rxrpc_get_call(struct rxrpc_call *call, enum rxrpc_call_trace op)
{
const void *here = __builtin_return_address(0);
int n = atomic_inc_return(&call->usage);
int m = atomic_read(&call->skb_count);
- trace_rxrpc_call(call, 3, n, m, here, 0);
+ trace_rxrpc_call(call, op, n, m, here, NULL);
}
/*
int n = atomic_inc_return(&call->usage);
int m = atomic_inc_return(&call->skb_count);
- trace_rxrpc_call(call, 4, n, m, here, skb);
+ trace_rxrpc_call(call, rxrpc_call_got_skb, n, m, here, skb);
}
/*
write_lock_bh(&call->state_lock);
call->state = RXRPC_CALL_DEAD;
write_unlock_bh(&call->state_lock);
- rxrpc_put_call(call);
+ rxrpc_put_call(call, rxrpc_call_put);
}
/*
/*
* release a call
*/
-void rxrpc_put_call(struct rxrpc_call *call)
+void rxrpc_put_call(struct rxrpc_call *call, enum rxrpc_call_trace op)
{
const void *here = __builtin_return_address(0);
int n, m;
n = atomic_dec_return(&call->usage);
m = atomic_read(&call->skb_count);
- trace_rxrpc_call(call, 5, n, m, here, NULL);
+ trace_rxrpc_call(call, op, n, m, here, NULL);
ASSERTCMP(n, >=, 0);
if (n == 0) {
_debug("call %d dead", call->debug_id);
n = atomic_dec_return(&call->usage);
m = atomic_dec_return(&call->skb_count);
- trace_rxrpc_call(call, 6, n, m, here, skb);
+ trace_rxrpc_call(call, rxrpc_call_put_skb, n, m, here, skb);
ASSERTCMP(n, >=, 0);
if (n == 0) {
_debug("call %d dead", call->debug_id);
}
read_unlock(&call->state_lock);
- rxrpc_get_call(call);
+ rxrpc_get_call(call, rxrpc_call_got);
if (sp->hdr.type == RXRPC_PACKET_TYPE_DATA &&
sp->hdr.flags & RXRPC_JUMBO_PACKET)
else
rxrpc_fast_process_packet(call, skb);
- rxrpc_put_call(call);
+ rxrpc_put_call(call, rxrpc_call_put);
goto done;
resend_final_ack:
_debug("final ack again");
- rxrpc_get_call(call);
+ rxrpc_get_call(call, rxrpc_call_got);
set_bit(RXRPC_CALL_EV_ACK_FINAL, &call->events);
rxrpc_queue_call(call);
goto free_unlock;
if (rx->sk.sk_state != RXRPC_SERVER_LISTENING) {
release_sock(&rx->sk);
if (continue_call)
- rxrpc_put_call(continue_call);
+ rxrpc_put_call(continue_call,
+ rxrpc_call_put);
return -ENODATA;
}
}
if (call != continue_call ||
skb->mark != RXRPC_SKB_MARK_DATA) {
release_sock(&rx->sk);
- rxrpc_put_call(continue_call);
+ rxrpc_put_call(continue_call, rxrpc_call_put);
_leave(" = %d [noncont]", copied);
return copied;
}
}
- rxrpc_get_call(call);
+ rxrpc_get_call(call, rxrpc_call_got);
/* copy the peer address and timestamp */
if (!continue_call) {
if (!continue_call)
continue_call = sp->call;
else
- rxrpc_put_call(call);
+ rxrpc_put_call(call, rxrpc_call_put);
call = NULL;
if (flags & MSG_PEEK) {
out:
release_sock(&rx->sk);
if (call)
- rxrpc_put_call(call);
+ rxrpc_put_call(call, rxrpc_call_put);
if (continue_call)
- rxrpc_put_call(continue_call);
+ rxrpc_put_call(continue_call, rxrpc_call_put);
_leave(" = %d [data]", copied);
return copied;
}
release_sock(&rx->sk);
- rxrpc_put_call(call);
+ rxrpc_put_call(call, rxrpc_call_put);
if (continue_call)
- rxrpc_put_call(continue_call);
+ rxrpc_put_call(continue_call, rxrpc_call_put);
_leave(" = %d", ret);
return ret;
copy_error:
_debug("copy error");
release_sock(&rx->sk);
- rxrpc_put_call(call);
+ rxrpc_put_call(call, rxrpc_call_put);
if (continue_call)
- rxrpc_put_call(continue_call);
+ rxrpc_put_call(continue_call, rxrpc_call_put);
_leave(" = %d", ret);
return ret;
wait_error:
finish_wait(sk_sleep(&rx->sk), &wait);
if (continue_call)
- rxrpc_put_call(continue_call);
+ rxrpc_put_call(continue_call, rxrpc_call_put);
if (copied)
copied = ret;
_leave(" = %d [waitfail %d]", copied, ret);
call = rxrpc_accept_call(rx, user_call_ID, NULL);
if (IS_ERR(call))
return PTR_ERR(call);
- rxrpc_put_call(call);
+ rxrpc_put_call(call, rxrpc_call_put);
return 0;
}
ret = rxrpc_send_data(rx, call, msg, len);
}
- rxrpc_put_call(call);
+ rxrpc_put_call(call, rxrpc_call_put);
_leave(" = %d", ret);
return ret;
}
/* get an extra ref on the call for the final-ACK generator to
* release */
- rxrpc_get_call(call);
+ rxrpc_get_call(call, rxrpc_call_got);
set_bit(RXRPC_CALL_EV_ACK_FINAL, &call->events);
if (try_to_del_timer_sync(&call->ack_timer) >= 0)
rxrpc_queue_call(call);