[ltt-dev] [PATCH] LTTNG: Make marker enabled in advance
Gui Jianfeng
guijianfeng at cn.fujitsu.com
Sun Mar 8 21:23:53 EDT 2009
Mathieu Desnoyers wrote:
> * Gui Jianfeng (guijianfeng at cn.fujitsu.com) wrote:
>> Mathieu Desnoyers wrote:
>>> * Gui Jianfeng (guijianfeng at cn.fujitsu.com) wrote:
>>>> Mathieu Desnoyers wrote:
>>>>> * Gui Jianfeng (guijianfeng at cn.fujitsu.com) wrote:
>>>>>> Mathieu Desnoyers wrote:
>>>>>>> * Gui Jianfeng (guijianfeng at cn.fujitsu.com) wrote:
>>>>>>>> Hi Mathieu,
>>>>>>>>
>>>>>>>> This patch makes marker enabled in advance.
>>>>>>>> IOW, even if the marker isn't present for the moment,
>>>>>>>> you can still enable it for future use.
>>>>>>>> As soon as the marker is inserted into kernel, tracing
>>>>>>>> work can be started immediately.
>>>>>>>>
>>>>>>>> Here is an example for using the user interface:
>>>>>>>> This patch assumes the marker control patch is applied.
>>>>>>>>
>>>>>>>> [root at localhost markers]# cd /mnt/debugfs/ltt/markers
>>>>>>>> [root at localhost markers]# mkdir fs
>>>>>>>> [root at localhost markers]# cd fs
>>>>>>>> [root at localhost fs]# mkdir close
>>>>>>>> [root at localhost fs]# cd close/
>>>>>>>> [root at localhost close]# ls
>>>>>>>> enable info
>>>>>>>> [root at localhost close]# echo 1 > enable
>>>>>>>> [root at localhost close]# cat enable
>>>>>>>> 2
>>>>>>>> [root at localhost close]# cat info
>>>>>>>> marker is not present now!
>>>>>>>> [root at localhost close]# modprobe fs_trace
>>>>>>>> [root at localhost close]# cat enable
>>>>>>>> 1
>>>>>>>> [root at localhost close]# cat info
>>>>>>>> format: "fd %u"
>>>>>>>> state: 1
>>>>>>>> event_id: 1
>>>>>>>> call: 0xc0468167
>>>>>>>> probe single : 0xc0520cdc
>>>>>>>>
>>>>>>>> Signed-off-by: Gui Jianfeng <guijianfeng at cn.fujitsu.com>
>>>>>>>> ---
>>>>>>>> ltt/ltt-trace-control.c | 357 ++++++++++++++++++++++++++++++++---------------
>>>>>>>> 1 files changed, 247 insertions(+), 110 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/ltt/ltt-trace-control.c b/ltt/ltt-trace-control.c
>>>>>>>> index 128db4e..7e1c32e 100644
>>>>>>>> --- a/ltt/ltt-trace-control.c
>>>>>>>> +++ b/ltt/ltt-trace-control.c
>>>>>>>> @@ -19,6 +19,7 @@
>>>>>>>> #include <linux/debugfs.h>
>>>>>>>> #include <linux/ltt-tracer.h>
>>>>>>>> #include <linux/notifier.h>
>>>>>>>> +#include <linux/mutex.h>
>>>>>>>>
>>>>>>>> #define LTT_CONTROL_DIR "control"
>>>>>>>> #define MARKERS_CONTROL_DIR "markers"
>>>>>>>> @@ -27,9 +28,240 @@
>>>>>>>>
>>>>>>>> #define LTT_WRITE_MAXLEN (128)
>>>>>>>>
>>>>>>>> +#define MARKER_ENABLE_MASK 0x7UL
>>>>>>> What is this doing ?
>>>>>> marker is 8 bytes aligned, the last 3 bit must 0.
>>>>>> I use these bits to identify whether the marker is enabled in advance.
>>>>>>
>>>>> Is there a clear gain to encode such information in the pointer bits ?
>>>>> Can we simply add a "char" somewhere which would be easier for the code
>>>>> reviewers ? I rarely found out that this addition of complexity was
>>>>> worth it, except when some updates need to be done atomically.
>>>> Hi Mathieu,
>>>>
>>>> I make use of inode->i_private of the file "enable" to store the corresponding
>>>> marker address. If marker isn't present in kernel, but someone want to enable
>>>> it in advance, inode->i_private will be 0x00000001. We don't need additional
>>>> space to store *Pre-enable* status.
>>>> If you have a better solution, could you give me some suggestions?
>>>>
>>> Oh ! I see, you keep a pointer to struct marker as i_private of the
>>> marker files in the debugfs tree. This is buggy, here is why :
>>>
>>> If the follow happens :
>>>
>>> module A has marker1
>>> module B has marker1 (too)
>>>
>>> We have :
>>>
>>> insmod module A
>>> -> marker1 debugfs files created, pointing to module A marker1
>>> insmod module B
>>> -> marker1 already exists, no update done, but "marker1" i_private
>>> still points to module A's marker1
>>> rmmod module A
>>> -> removing marker1, but module B still has one which should show up
>>> in the directory tree.
>> marker1 will not show up any more, it will gone when removing module A.
>> So this won't cause serious problem. but this is a problem for sure,
>> beacuse current implementation can't handle same name marker....
>>
>>> How to fix this ? Simply by _not_ keeping a direct reference to
>>> struct marker within ltt-trace-control.c.
>>>
>>> We have a hash table in kernel/marker.c which takes care of exactly
>>> this: it keeps a reference could of each marker loaded. Therefore, if
>>> you need to get information about the state of such marker, you should
>>> really use primitives like include/linux/marker.h:is_marker_enabled(),
>>> and create your own primitives to export the information you need from
>>> marker.c.
>>>
>>> This will solve you "is enabled" problem, because this hash table keeps
>>> track of _activated_ markers. Therefore, for each marker you encounter
>>> in the marker section (what you are iterating on upon module load
>>> notification), you just have to query the is_marker_enabled() state for
>>> the channel and marker name to get its state.
>>>
>>> You will however need to be called also when the marker state changes.
>>> One way to do this would be to add a marker update notifier chain to
>>> kernel/marker.c which would call your notifier callback.
>>>
>>> Looking at the register_module_notifier() use you are doing in
>>> ltt_trace_control makes think of the following : kernel/marker.c should
>>> use register_module_notifier(), but your module should not be called by
>>> module.c. It should rather be called by marker.c, which is the module
>>> which modifies the data structures your are interested to follow.
>>>
>>> Therefore, once you do that, keeping track of the marker state changes
>>> will become _much_ easier, and you won't need any of these weird pointer
>>> handling stuff.
>
> Hi Gui,
>
>> buffering a marker pointer can save search-time. IOW, when read "info" or "enable"
>> to query information for a given marker, it has to iterate all the marker section
>> in kernel and each modules to find out the marker.
>
> How often to you need the marker info ?
>
>> and this also save the time for
>> calling is_marker_enabled() to search the hash table.
>>
>> My solution to solve the "same name marker" problem is that buffering the marker
>> pointer in i_private if a marker doesn't have another same name marker. If there are
>> two same name markers available, the 2nd lowest bit of i_private will indicate this situation
>> and we need to iterate all the markers in kernel and modules to find out the corresponding
>> markers.
>>
>
> You are optimizing a slow path. This is non-sense. Please use a solution
> that is clean and works (and implies a hash table lookup) rather than to
> do caches that will have no observable performance effects. And I cannot
> stress enough the fact that the current situation is broken and will
> leave marker modules unavailable in some module load/unload sequence.
> We do not care about performance for marker connection/disconnection,
> because this operation is rarely done, but we care a great deal about
> correctness.
OK, Will change.
Thanks for your comments. ;)
>
>
--
Regards
Gui Jianfeng
More information about the lttng-dev
mailing list