|
Packit Service |
d40955 |
/*
|
|
Packit Service |
d40955 |
* Copyright (c) 2020 Red Hat, Inc.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
d40955 |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
d40955 |
* as published by the Free Software Foundation; either version 2
|
|
Packit Service |
d40955 |
* of the License, or (at your option) any later version.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
d40955 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
d40955 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
d40955 |
* GNU General Public License for more details.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
d40955 |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
d40955 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
d40955 |
* 02110-1301, USA.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/workQueueStats.h#2 $
|
|
Packit Service |
d40955 |
*/
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
#ifndef WORK_QUEUE_STATS_H
|
|
Packit Service |
d40955 |
#define WORK_QUEUE_STATS_H
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
#include "workQueue.h"
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
#include "timeUtils.h"
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
#include "histogram.h"
|
|
Packit Service |
d40955 |
#include "workItemStats.h"
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
// Defined in workQueueInternals.h after inclusion of workQueueStats.h.
|
|
Packit Service |
d40955 |
struct simpleWorkQueue;
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/*
|
|
Packit Service |
d40955 |
* Tracking statistics.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* Cache line contention issues:
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* In workItemStats, there are read-only fields accessed mostly by
|
|
Packit Service |
d40955 |
* work submitters, then fields updated by the work submitters (for
|
|
Packit Service |
d40955 |
* which there will be contention), then fields rarely if ever updated
|
|
Packit Service |
d40955 |
* (more than two cache lines' worth), then fields updated only by the
|
|
Packit Service |
d40955 |
* worker thread. The trailing fields here are updated only by the
|
|
Packit Service |
d40955 |
* worker thread.
|
|
Packit Service |
d40955 |
*/
|
|
Packit Service |
d40955 |
typedef struct kvdoWorkQueueStats {
|
|
Packit Service |
d40955 |
// Per-work-function counters and optional nanosecond timing data
|
|
Packit Service |
d40955 |
KvdoWorkItemStats workItemStats;
|
|
Packit Service |
d40955 |
// How often we go to sleep waiting for work
|
|
Packit Service |
d40955 |
uint64_t waits;
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
// Run time data, for monitoring utilization levels.
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
// Thread start time, from which we can compute lifetime thus far.
|
|
Packit Service |
d40955 |
uint64_t startTime;
|
|
Packit Service |
d40955 |
/*
|
|
Packit Service |
d40955 |
* Time the thread has not been blocked waiting for a new work item,
|
|
Packit Service |
d40955 |
* nor in cond_resched(). This will include time the thread has been
|
|
Packit Service |
d40955 |
* blocked by some kernel function invoked by the work functions
|
|
Packit Service |
d40955 |
* (e.g., waiting for socket buffer space).
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* This is not redundant with runTimeBeforeRescheduleHistogram, as
|
|
Packit Service |
d40955 |
* the latter doesn't count run time not followed by a cond_resched
|
|
Packit Service |
d40955 |
* call.
|
|
Packit Service |
d40955 |
*/
|
|
Packit Service |
d40955 |
atomic64_t runTime;
|
|
Packit Service |
d40955 |
// Time the thread has been suspended via cond_resched().
|
|
Packit Service |
d40955 |
// (Duplicates data hidden within rescheduleTimeHistogram.)
|
|
Packit Service |
d40955 |
atomic64_t rescheduleTime;
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
// Histogram of the queue times of work items (microseconds)
|
|
Packit Service |
d40955 |
Histogram *queueTimeHistogram;
|
|
Packit Service |
d40955 |
// How busy we are when cond_resched is called
|
|
Packit Service |
d40955 |
Histogram *rescheduleQueueLengthHistogram;
|
|
Packit Service |
d40955 |
// Histogram of the time cond_resched makes us sleep for (microseconds)
|
|
Packit Service |
d40955 |
Histogram *rescheduleTimeHistogram;
|
|
Packit Service |
d40955 |
// Histogram of the run time between cond_resched calls (microseconds)
|
|
Packit Service |
d40955 |
Histogram *runTimeBeforeRescheduleHistogram;
|
|
Packit Service |
d40955 |
// Histogram of the time schedule_timeout lets us sleep for (microseconds)
|
|
Packit Service |
d40955 |
Histogram *scheduleTimeHistogram;
|
|
Packit Service |
d40955 |
// How long from thread wakeup call to thread actually running (microseconds)
|
|
Packit Service |
d40955 |
Histogram *wakeupLatencyHistogram;
|
|
Packit Service |
d40955 |
// How much work is pending by the time we start running
|
|
Packit Service |
d40955 |
Histogram *wakeupQueueLengthHistogram;
|
|
Packit Service |
d40955 |
} KvdoWorkQueueStats;
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Initialize the work queue's statistics tracking.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param stats The statistics structure
|
|
Packit Service |
d40955 |
* @param queueKObject The sysfs directory kobject for the work queue
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @return 0 or a kernel error code
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
int initializeWorkQueueStats(KvdoWorkQueueStats *stats,
|
|
Packit Service |
d40955 |
struct kobject *queueKObject)
|
|
Packit Service |
d40955 |
__attribute__((warn_unused_result));
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Tear down any allocated storage or objects for statistics tracking.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param stats The statistics structure
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
void cleanupWorkQueueStats(KvdoWorkQueueStats *stats);
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Update the work queue statistics tracking to note the enqueueing of
|
|
Packit Service |
d40955 |
* a work item.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param stats The statistics structure
|
|
Packit Service |
d40955 |
* @param item The work item being enqueued
|
|
Packit Service |
d40955 |
* @param priority The priority of the work item
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
static inline void updateStatsForEnqueue(KvdoWorkQueueStats *stats,
|
|
Packit Service |
d40955 |
KvdoWorkItem *item,
|
|
Packit Service |
d40955 |
int priority)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
updateWorkItemStatsForEnqueue(&stats->workItemStats, item, priority);
|
|
Packit Service |
d40955 |
item->enqueueTime = currentTime(CLOCK_MONOTONIC);
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Update the work queue statistics tracking to note the dequeueing of
|
|
Packit Service |
d40955 |
* a work item.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param stats The statistics structure
|
|
Packit Service |
d40955 |
* @param item The work item being enqueued
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
static inline void updateStatsForDequeue(KvdoWorkQueueStats *stats,
|
|
Packit Service |
d40955 |
KvdoWorkItem *item)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
updateWorkItemStatsForDequeue(&stats->workItemStats, item);
|
|
Packit Service |
d40955 |
enterHistogramSample(stats->queueTimeHistogram,
|
|
Packit Service |
d40955 |
(currentTime(CLOCK_MONOTONIC) - item->enqueueTime) / 1000);
|
|
Packit Service |
d40955 |
item->enqueueTime = 0;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Write the work queue's accumulated statistics to the kernel log.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* The queue pointer is needed so that its address and name can be
|
|
Packit Service |
d40955 |
* logged along with the statistics.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param queue The work queue
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
void logWorkQueueStats(const struct simpleWorkQueue *queue);
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Format the thread lifetime, run time, and suspend time into a
|
|
Packit Service |
d40955 |
* supplied buffer for reporting via sysfs.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param [in] stats The stats structure containing the run-time info
|
|
Packit Service |
d40955 |
* @param [out] buffer The buffer in which to report the info
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
ssize_t formatRunTimeStats(const KvdoWorkQueueStats *stats, char *buffer);
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
#endif // WORK_QUEUE_STATS_H
|