diff options
author | Alexander Shishkin <alexander.shishkin@linux.intel.com> | 2019-06-27 15:51:47 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-07-03 17:45:57 +0200 |
commit | f505e91ef511a20b2bc3d0eaca41faecdb715027 (patch) | |
tree | 7610e38b15129e8017dbf60dbd769909da4e0027 /drivers | |
parent | bbbc08a154a1750371f8347a5353819551d11abb (diff) | |
download | linux-f505e91ef511a20b2bc3d0eaca41faecdb715027.tar.bz2 |
intel_th: msu: Start read iterator from a non-empty window
In multi-window mode, the read iterator is supposed to start from the
window with the oldest data, which is, chronologically, the next window
after the one with the newest data. This, however, fails to take into
account the potentially empty windows, so in short trace sessions it's
possible to have a lot of zeroes read from the character device first.
Fix this by skipping over the empty windows in initialization of the
read iterator.
Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20190627125152.54905-5-alexander.shishkin@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/hwtracing/intel_th/msu.c | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/drivers/hwtracing/intel_th/msu.c b/drivers/hwtracing/intel_th/msu.c index aedfd8629e58..8ab28e5fb366 100644 --- a/drivers/hwtracing/intel_th/msu.c +++ b/drivers/hwtracing/intel_th/msu.c @@ -189,17 +189,18 @@ static struct msc_window *msc_next_window(struct msc_window *win) } /** - * msc_oldest_window() - locate the window with oldest data + * msc_find_window() - find a window matching a given sg_table * @msc: MSC device + * @sgt: SG table of the window + * @nonempty: skip over empty windows * - * This should only be used in multiblock mode. Caller should hold the - * msc::user_count reference. - * - * Return: the oldest window with valid data + * Return: MSC window structure pointer or NULL if the window + * could not be found. */ -static struct msc_window *msc_oldest_window(struct msc *msc) +static struct msc_window * +msc_find_window(struct msc *msc, struct sg_table *sgt, bool nonempty) { - struct msc_window *win, *next = msc_next_window(msc->cur_win); + struct msc_window *win; unsigned int found = 0; if (list_empty(&msc->win_list)) @@ -211,17 +212,40 @@ static struct msc_window *msc_oldest_window(struct msc *msc) * something like 2, in which case we're good */ list_for_each_entry(win, &msc->win_list, entry) { - if (win == next) + if (win->sgt == sgt) found++; /* skip the empty ones */ - if (msc_block_is_empty(msc_win_block(win, 0))) + if (nonempty && msc_block_is_empty(msc_win_block(win, 0))) continue; if (found) return win; } + return NULL; +} + +/** + * msc_oldest_window() - locate the window with oldest data + * @msc: MSC device + * + * This should only be used in multiblock mode. Caller should hold the + * msc::user_count reference. + * + * Return: the oldest window with valid data + */ +static struct msc_window *msc_oldest_window(struct msc *msc) +{ + struct msc_window *win; + + if (list_empty(&msc->win_list)) + return NULL; + + win = msc_find_window(msc, msc_next_window(msc->cur_win)->sgt, true); + if (win) + return win; + return list_first_entry(&msc->win_list, struct msc_window, entry); } |