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>
This commit is contained in:
Alexander Shishkin 2019-06-27 15:51:47 +03:00 committed by Greg Kroah-Hartman
parent bbbc08a154
commit f505e91ef5
1 changed files with 33 additions and 9 deletions

View File

@ -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);
}