📄 trace.c
字号:
p_new_event->next = custom_events; p_new_event->prev = custom_events->prev; custom_events->prev->next = p_new_event; custom_events->prev = p_new_event; write_unlock(&custom_list_lock); /* Log the event creation event */ trace_event(TRACE_EV_NEW_EVENT, &(p_new_event->event)); /* Return new event ID */ return p_new_event->event.id;}int trace_create_event(char* pm_event_type, char* pm_event_desc, int pm_format_type, char* pm_format_data){ return _trace_create_event(pm_event_type, pm_event_desc, pm_format_type, pm_format_data, 0);}int trace_create_owned_event(char* pm_event_type, char* pm_event_desc, int pm_format_type, char* pm_format_data, pid_t pm_owner_pid){ return _trace_create_event(pm_event_type, pm_event_desc, pm_format_type, pm_format_data, pm_owner_pid);}/******************************************************* * Destroy a created event type * Parameters : * pm_event_id, the Id returned by trace_create_event() * Return values : * NONE *******************************************************/void trace_destroy_event(int pm_event_id){ struct custom_event_desc* p_event_desc; /* Generic event description pointer */ /* Lock the table for writting */ write_lock(&custom_list_lock); /* Go through the event description list */ for(p_event_desc = custom_events->next; p_event_desc != custom_events; p_event_desc = p_event_desc->next) if(p_event_desc->event.id == pm_event_id) break; /* If we found something */ if(p_event_desc != custom_events) { /* Remove the event fromt the list */ p_event_desc->next->prev = p_event_desc->prev; p_event_desc->prev->next = p_event_desc->next; /* Free the memory used by this event */ kfree(p_event_desc); } /* Unlock the table for writting */ write_unlock(&custom_list_lock);}/******************************************************* * Destroy an owner's events * Parameters : * pm_owner_pid, the PID of the owner who's events are to * be deleted. * Return values : * NONE *******************************************************/void trace_destroy_owners_events(pid_t pm_owner_pid){ struct custom_event_desc* p_temp_event; /* Temporary event */ struct custom_event_desc* p_event_desc; /* Generic event description pointer */ /* Lock the table for writting */ write_lock(&custom_list_lock); /* Start at the first event in the list */ p_event_desc = custom_events->next; /* Go through the event description list */ while(p_event_desc != custom_events) { /* Keep pointer to next event */ p_temp_event = p_event_desc->next; /* Does this event belong to the same owner */ if(p_event_desc->owner_pid == pm_owner_pid) { /* Remove the event fromt the list */ p_event_desc->next->prev = p_event_desc->prev; p_event_desc->prev->next = p_event_desc->next; /* Free the memory used by this event */ kfree(p_event_desc); } /* Go to next event */ p_event_desc = p_temp_event; } /* Unlock the table for writting */ write_unlock(&custom_list_lock);}/******************************************************* * Relog the declarations of custom events. This is * necessary to make sure that even though the event * creation might not have taken place during a trace, * that all custom events be part of all traces. Hence, * if a custom event occurs during a trace, we can be * sure that it's definition is part of the trace. * Parameters : * NONE * Return values : * NONE *******************************************************/void trace_reregister_custom_events(void){ struct custom_event_desc* p_event_desc; /* Generic event description pointer */ /* Lock the table for reading */ read_lock(&custom_list_lock); /* Go through the event description list */ for(p_event_desc = custom_events->next; p_event_desc != custom_events; p_event_desc = p_event_desc->next) /* Log the event creation event */ trace_event(TRACE_EV_NEW_EVENT, &(p_event_desc->event)); /* Unlock the table for reading */ read_unlock(&custom_list_lock);}/******************************************************* * Trace a formatted event * Parameters : * pm_event_id, the event Id provided upon creation * ..., printf-like data that will be used to fill the * event string. * Return values : * 0, all is OK * -ENOMEDIUM, there isn't a registered tracer or this * event doesn't exist. * -EBUSY, tracing hasn't started yet *******************************************************/int trace_std_formatted_event(int pm_event_id, ...){ int l_string_size; /* Size of the string outputed by vsprintf() */ char l_string[CUSTOM_EVENT_FINAL_STR_LEN]; /* Final formatted string */ va_list l_var_arg_list; /* Variable argument list */ trace_custom l_custom; /* Custom event */ struct custom_event_desc* p_event_desc; /* Generic event description pointer */ /* Lock the table for reading */ read_lock(&custom_list_lock); /* Go through the event description list */ for(p_event_desc = custom_events->next; p_event_desc != custom_events; p_event_desc = p_event_desc->next) if(p_event_desc->event.id == pm_event_id) break; /* If we haven't found anything */ if(p_event_desc == custom_events) { /* Unlock the table for reading */ read_unlock(&custom_list_lock); /* No such thing */ return -ENOMEDIUM; } /* Set custom event Id */ l_custom.id = pm_event_id; /* Initialize variable argument list access */ va_start(l_var_arg_list, pm_event_id); /* Print the description out to the temporary buffer */ l_string_size = vsprintf(l_string, p_event_desc->event.desc, l_var_arg_list); /* Unlock the table for reading */ read_unlock(&custom_list_lock); /* Facilitate return to caller */ va_end(l_var_arg_list); /* Set the size of the event */ l_custom.data_size = (uint32_t) (l_string_size + 1); /* Set the pointer to the event data */ l_custom.data = l_string; /* Log the custom event */ return trace_event(TRACE_EV_CUSTOM, &l_custom);}/******************************************************* * Trace a raw event * Parameters : * pm_event_id, the event Id provided upon creation * pm_event_size, the size of the data provided * pm_event_data, data buffer describing event * Return values : * 0, all is OK * -ENOMEDIUM, there isn't a registered tracer or this * event doesn't exist. * -EBUSY, tracing hasn't started yet *******************************************************/int trace_raw_event(int pm_event_id, int pm_event_size, void* pm_event_data){ trace_custom l_custom; /* Custom event */ struct custom_event_desc* p_event_desc; /* Generic event description pointer */ /* Lock the table for reading */ read_lock(&custom_list_lock); /* Go through the event description list */ for(p_event_desc = custom_events->next; p_event_desc != custom_events; p_event_desc = p_event_desc->next) if(p_event_desc->event.id == pm_event_id) break; /* Unlock the table for reading */ read_unlock(&custom_list_lock); /* If we haven't found anything */ if(p_event_desc == custom_events) /* No such thing */ return -ENOMEDIUM; /* Set custom event Id */ l_custom.id = pm_event_id; /* Set the data size */ if(pm_event_size <= CUSTOM_EVENT_MAX_SIZE) l_custom.data_size = (uint32_t) pm_event_size; else l_custom.data_size = (uint32_t) CUSTOM_EVENT_MAX_SIZE; /* Set the pointer to the event data */ l_custom.data = pm_event_data; /* Log the custom event */ return trace_event(TRACE_EV_CUSTOM, &l_custom);}/******************************************************* * Trace an event * Parameters : * pm_event_id, the event's ID (check out trace.h) * pm_event_struct, the structure describing the event * Return values : * 0, all is OK * -ENOMEDIUM, there isn't a registered tracer * -EBUSY, tracing hasn't started yet *******************************************************/int trace_event(uint8_t pm_event_id, void* pm_event_struct){ int l_ret_value; /* The return value */ struct trace_callback_table_entry* p_tct_entry; /* Pointer to trace callback table entry */ /* Lock registration variables */ read_lock(&tracer_register_lock); /* Is there a tracer registered */ if(tracer_registered != 1) l_ret_value = -ENOMEDIUM; else /* Call the tracer */ l_ret_value = tracer->trace(pm_event_id, pm_event_struct); /* Unlock registration variables */ read_unlock(&tracer_register_lock); /* Is this a native event */ if(pm_event_id <= TRACE_EV_MAX) { /* Are there any callbacks to call */ if(trace_callback_table[pm_event_id - 1].next != NULL) { /* Call all the callbacks linked to this event */ for(p_tct_entry = trace_callback_table[pm_event_id - 1].next; p_tct_entry != NULL; p_tct_entry = p_tct_entry->next) p_tct_entry->callback(pm_event_id, pm_event_struct); } } /* Give the return value */ return l_ret_value;}/******************************************************* * Initialize trace facility * Parameters : * NONE * Return values : * NONE *******************************************************/static int __init trace_init(void){ int i; /* Generic index */ /* Initialize callback table */ for(i = 0; i < TRACE_EV_MAX; i++) { trace_callback_table[i].callback = NULL; trace_callback_table[i].next = NULL; } /* Next event ID to be used */ next_event_id = TRACE_EV_MAX + 1; /* Initialize custom events list */ custom_events = &custom_events_head; custom_events->next = custom_events; custom_events->prev = custom_events; /* Everything is OK */ return 0;}module_init(trace_init);/* Export symbols so that can be visible from outside this file */EXPORT_SYMBOL(register_tracer);EXPORT_SYMBOL(unregister_tracer);EXPORT_SYMBOL(trace_set_config);EXPORT_SYMBOL(trace_get_config);EXPORT_SYMBOL(trace_register_callback);EXPORT_SYMBOL(trace_unregister_callback);EXPORT_SYMBOL(trace_create_event);EXPORT_SYMBOL(trace_create_owned_event);EXPORT_SYMBOL(trace_destroy_event);EXPORT_SYMBOL(trace_destroy_owners_events);EXPORT_SYMBOL(trace_reregister_custom_events);EXPORT_SYMBOL(trace_std_formatted_event);EXPORT_SYMBOL(trace_raw_event);EXPORT_SYMBOL(trace_event);#if !defined(CONFIG_PPC) && !defined(__sh__)EXPORT_SYMBOL(irq_desc);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -