Blame source/vdo/kernel/workQueueStats.h

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