]> git.karo-electronics.de Git - linux-beck.git/commitdiff
greybus: add operation traces
authorAlex Elder <elder@linaro.org>
Fri, 20 May 2016 16:59:57 +0000 (11:59 -0500)
committerGreg Kroah-Hartman <gregkh@google.com>
Sat, 21 May 2016 00:12:25 +0000 (17:12 -0700)
Define a new gb_operation event class, and define and use trace
events that record when an operation is created, finally destroyed,
and when its active count changes.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/greybus_trace.h
drivers/staging/greybus/operation.c

index 849cfa095aac4bbd1778e76f4252b372cb84a6b3..3b4875d91c32f324879d914adab1820cfcaabbc4 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/tracepoint.h>
 
 struct gb_message;
+struct gb_operation;
 struct gb_host_device;
 
 #define gb_bundle_name(message)                                                \
@@ -111,6 +112,74 @@ DEFINE_EVENT(gb_message, gb_message_cancel_incoming,
        TP_ARGS(message)
 );
 
+DECLARE_EVENT_CLASS(gb_operation,
+
+       TP_PROTO(struct gb_operation *operation),
+
+       TP_ARGS(operation),
+
+       TP_STRUCT__entry(
+               __field(u16, cport_id)  /* CPort of HD side of connection */
+               __field(u16, id)        /* Operation ID */
+               __field(u8, type)
+               __field(unsigned long, flags)
+               __field(int, active)
+               __field(int, waiters)
+               __field(int, errno)
+       ),
+
+       TP_fast_assign(
+               __entry->cport_id = operation->connection->hd_cport_id;
+               __entry->id = operation->id;
+               __entry->type = operation->type;
+               __entry->flags = operation->flags;
+               __entry->active = operation->active;
+               __entry->waiters = atomic_read(&operation->waiters);
+               __entry->errno = operation->errno;
+       ),
+
+       TP_printk("id=%04x type=0x%02x cport_id=%04x flags=0x%lx active=%d waiters=%d errno=%d",
+                 __entry->id, __entry->cport_id, __entry->type, __entry->flags,
+                 __entry->active, __entry->waiters, __entry->errno)
+);
+
+#define DEFINE_OPERATION_EVENT(name)                                   \
+               DEFINE_EVENT(gb_operation, name,                        \
+                               TP_PROTO(struct gb_operation *operation), \
+                               TP_ARGS(operation))
+
+/*
+ * Occurs after a new operation is created for an outgoing request
+ * has been successfully created.
+ */
+DEFINE_OPERATION_EVENT(gb_operation_create);
+
+/*
+ * Occurs after a new operation has been created for an incoming
+ * request has been successfully created and initialized.
+ */
+DEFINE_OPERATION_EVENT(gb_operation_create_incoming);
+
+/*
+ * Occurs when the last reference to an operation has been dropped,
+ * prior to freeing resources.
+ */
+DEFINE_OPERATION_EVENT(gb_operation_destroy);
+
+/*
+ * Occurs when an operation has been marked active, after updating
+ * its active count.
+ */
+DEFINE_OPERATION_EVENT(gb_operation_get_active);
+
+/*
+ * Occurs when an operation has been marked active, before updating
+ * its active count.
+ */
+DEFINE_OPERATION_EVENT(gb_operation_put_active);
+
+#undef DEFINE_OPERATION_EVENT
+
 DECLARE_EVENT_CLASS(gb_host_device,
 
        TP_PROTO(struct gb_host_device *hd, u16 intf_cport_id,
index b7cc59d0a2521922dfae920e00a2ecbcdc9581d7..259bd920e715db60b68c1f483136e76e85ab8acb 100644 (file)
@@ -57,6 +57,8 @@ static int gb_operation_get_active(struct gb_operation *operation)
        if (operation->active++ == 0)
                list_add_tail(&operation->links, &connection->operations);
 
+       trace_gb_operation_get_active(operation);
+
        spin_unlock_irqrestore(&connection->lock, flags);
 
        return 0;
@@ -69,6 +71,9 @@ static void gb_operation_put_active(struct gb_operation *operation)
        unsigned long flags;
 
        spin_lock_irqsave(&connection->lock, flags);
+
+       trace_gb_operation_get_active(operation);
+
        if (--operation->active == 0) {
                list_del(&operation->links);
                if (atomic_read(&operation->waiters))
@@ -536,6 +541,8 @@ gb_operation_create_flags(struct gb_connection *connection,
                                size_t response_size, unsigned long flags,
                                gfp_t gfp)
 {
+       struct gb_operation *operation;
+
        if (WARN_ON_ONCE(type == GB_REQUEST_TYPE_INVALID))
                return NULL;
        if (WARN_ON_ONCE(type & GB_MESSAGE_TYPE_RESPONSE))
@@ -544,9 +551,14 @@ gb_operation_create_flags(struct gb_connection *connection,
        if (WARN_ON_ONCE(flags & ~GB_OPERATION_FLAG_USER_MASK))
                flags &= GB_OPERATION_FLAG_USER_MASK;
 
-       return gb_operation_create_common(connection, type,
+       operation = gb_operation_create_common(connection, type,
                                                request_size, response_size,
                                                flags, gfp);
+       if (operation)
+               trace_gb_operation_create(operation);
+
+       return operation;
+
 }
 EXPORT_SYMBOL_GPL(gb_operation_create_flags);
 
@@ -581,6 +593,7 @@ gb_operation_create_incoming(struct gb_connection *connection, u16 id,
 
        operation->id = id;
        memcpy(operation->request->header, data, size);
+       trace_gb_operation_create_incoming(operation);
 
        return operation;
 }
@@ -603,6 +616,8 @@ static void _gb_operation_destroy(struct kref *kref)
 
        operation = container_of(kref, struct gb_operation, kref);
 
+       trace_gb_operation_destroy(operation);
+
        if (operation->response)
                gb_operation_message_free(operation->response);
        gb_operation_message_free(operation->request);