[Crash-utility] [PATCH] fix the accounting of RSS when SPLIT_RSS_ACCOUNTING is enabled
vinayak menon
vinayakm.list at gmail.com
Tue Oct 29 06:29:34 UTC 2013
On Tue, Oct 29, 2013 at 1:36 AM, Dave Anderson <anderson at redhat.com> wrote:
>
>
> Hi Vinayak,
>
> Good catch -- it certainly should be fixed. The devil is in the details of how
> best to accomplish it...
>
> On the face of it, it would seem that the task group list gathering via do_list()
> would be the best way. The problem is that it could potentially cause the "ps"
> command to fail on live systems if the list becomes invalid, or is invalid with
> respect to the pre-gathered set of tasks that get captured prior to execution
> of the command.
>
> Prior to each crash command whose command_table_entry structure contains the
> REFRESH_TASK_TABLE flag (as does "ps"), the tt->refresh_task_table() function
> is called to scan the kernel's pid_hash[] for a stable set of tasks. And only
> those tasks are accessed or used by that crash command instance.
>
> By calling do_list(), it's conceivable (although fairly unlikely) that the command
> could go either go off into the weeds following a list that's being modified, or
> if the list has changed since the "stable" list was gathered prior to the command.
> So preferably, it would be best if the new functionality could be constrained to
> the stable set of pre-gathered tasks -- again if for no other reason than the fact
> that the crash utility only uses the pre-gathered task-set whenever it parses tasks.
>
> There's also another potential problem in having get_task_mem_usage() use
> open_tmpfile(). Since it's a function that gets called by other functions
> or macros (IN_TASK_VMA() for example), it's possible that the caller may
> also be operating inside an open_tmpfile() area, and open_tmpfile() is not
> recursive. In those internal cases, open_tmpfile2() could be used, but again,
> it's probably best to avoid the do_list() call.
>
> So I tinkered with an optional manner of checking the thread group list, i.e.,
> like this:
>
> if (VALID_MEMBER(task_struct_rss_stat)) {
> int i, cnt;
> int sync_rss;
> ulong tgid;
> struct task_context *tc1;
>
> tgid = task_tgid(task);
>
> tc1 = FIRST_CONTEXT();
> for (i = cnt = 0; i < RUNNING_TASKS(); i++, tc1++) {
> if (task_tgid(tc1->task) != tgid)
> continue;
>
> /* count 0 -> filepages */
> if (!readmem(tc1->task +
> OFFSET(task_struct_rss_stat) +
> OFFSET(task_rss_stat_count), KVADDR,
> &sync_rss,
> sizeof(int), "task_struct rss_stat 0",
> RETURN_ON_ERROR))
> continue;
>
> rss += sync_rss;
>
> /* count 1 -> anonpages */
> if (!readmem(tc1->task +
> OFFSET(task_struct_rss_stat) +
> OFFSET(task_rss_stat_count) + sizeof(int),
> KVADDR, &sync_rss,
> sizeof(int), "task_struct rss_stat 0",
> RETURN_ON_ERROR))
> continue;
>
> rss += sync_rss;
> }
> }
>
> It's inefficient in comparison to using do_list(), but it does guarantee
> safety on live systems.
>
> A couple other minor issues -- the two readmem() type strings above both
> indicate "rss_stat 0", so they should be differentiated with strings indicating
> "task_struct rss_stat MM_FILEPAGES" and "task_struct rss_stat MM_ANONPAGES".
>
> And lastly, since MEMBER_EXISTS() and MEMBER_OFFSET_INIT() do essentially
> the same thing, it simpler in this case to just call MEMBER_OFFSET_INIT()
> the 3 times without any MEMBER_EXISTS() conditionalization:
>
> + if (MEMBER_EXISTS("task_struct", "thread_group"))
> + MEMBER_OFFSET_INIT(task_struct_thread_group, "task_struct",
> + "thread_group");
> +
> + if (MEMBER_EXISTS("task_struct", "rss_stat")) {
> + MEMBER_OFFSET_INIT(task_struct_rss_stat, "task_struct",
> + "rss_stat");
> + MEMBER_OFFSET_INIT(task_rss_stat_count, "task_rss_stat",
> + "count");
> + }
> +
>
> If the members don't exist, they will just get set to INVALID_OFFSET (-1).
>
> What do you think?
>
> Dave
>
Hi Dave,
I have attached an updated patch with changes as per your suggestion.
Vinayak
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-fix-rss-accouting.patch
Type: application/octet-stream
Size: 3406 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/crash-utility/attachments/20131029/289e0ed6/attachment.obj>
More information about the Crash-utility
mailing list