|
Packit Service |
b3514a |
/*
|
|
Packit Service |
b3514a |
* Copyright (c) 2020 Red Hat, Inc.
|
|
Packit Service |
b3514a |
*
|
|
Packit Service |
b3514a |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
b3514a |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
b3514a |
* as published by the Free Software Foundation; either version 2
|
|
Packit Service |
b3514a |
* of the License, or (at your option) any later version.
|
|
Packit Service |
b3514a |
*
|
|
Packit Service |
b3514a |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
b3514a |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
b3514a |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
b3514a |
* GNU General Public License for more details.
|
|
Packit Service |
b3514a |
*
|
|
Packit Service |
b3514a |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
b3514a |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
b3514a |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
b3514a |
* 02110-1301, USA.
|
|
Packit Service |
b3514a |
*
|
|
Packit Service |
b3514a |
* $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/deadlockQueue.h#1 $
|
|
Packit Service |
b3514a |
*/
|
|
Packit Service |
b3514a |
|
|
Packit Service |
b3514a |
#ifndef DEADLOCK_QUEUE_H
|
|
Packit Service |
b3514a |
#define DEADLOCK_QUEUE_H
|
|
Packit Service |
b3514a |
|
|
Packit Service |
b3514a |
#include <linux/kernel.h>
|
|
Packit Service |
b3514a |
|
|
Packit Service |
b3514a |
#include "bio.h"
|
|
Packit Service |
b3514a |
|
|
Packit Service |
b3514a |
/**
|
|
Packit Service |
b3514a |
* A holding space for incoming bios if we're not able to block until VIOs
|
|
Packit Service |
b3514a |
* become available to process them.
|
|
Packit Service |
b3514a |
**/
|
|
Packit Service |
b3514a |
typedef struct deadlockQueue {
|
|
Packit Service |
b3514a |
/* Protection for the other fields. */
|
|
Packit Service |
b3514a |
spinlock_t lock;
|
|
Packit Service |
b3514a |
/* List of bios we had to accept but don't have VIOs for. */
|
|
Packit Service |
b3514a |
struct bio_list list;
|
|
Packit Service |
b3514a |
/*
|
|
Packit Service |
b3514a |
* Arrival time to use for statistics tracking for the above bios, since we
|
|
Packit Service |
b3514a |
* haven't the space to store individual arrival times for each.
|
|
Packit Service |
b3514a |
*/
|
|
Packit Service |
b3514a |
Jiffies arrivalTime;
|
|
Packit Service |
b3514a |
} DeadlockQueue;
|
|
Packit Service |
b3514a |
|
|
Packit Service |
b3514a |
/**
|
|
Packit Service |
b3514a |
* Initialize the DeadlockQueue structure.
|
|
Packit Service |
b3514a |
*
|
|
Packit Service |
b3514a |
* @param queue The structure to initialize
|
|
Packit Service |
b3514a |
**/
|
|
Packit Service |
b3514a |
void initializeDeadlockQueue(DeadlockQueue *queue);
|
|
Packit Service |
b3514a |
|
|
Packit Service |
b3514a |
/**
|
|
Packit Service |
b3514a |
* Add an incoming bio to the list of saved-up bios we're not ready to start
|
|
Packit Service |
b3514a |
* processing yet.
|
|
Packit Service |
b3514a |
*
|
|
Packit Service |
b3514a |
* This excess buffering on top of what the caller implements is generally a
|
|
Packit Service |
b3514a |
* bad idea, and should be used only when necessary, such as to avoid a
|
|
Packit Service |
b3514a |
* possible deadlock situation.
|
|
Packit Service |
b3514a |
*
|
|
Packit Service |
b3514a |
* @param queue The incoming-bio queue structure
|
|
Packit Service |
b3514a |
* @param bio The new incoming bio to save
|
|
Packit Service |
b3514a |
* @param arrivalTime The arrival time of this new bio
|
|
Packit Service |
b3514a |
**/
|
|
Packit Service |
b3514a |
void addToDeadlockQueue(DeadlockQueue *queue, BIO *bio, Jiffies arrivalTime);
|
|
Packit Service |
b3514a |
|
|
Packit Service |
b3514a |
/**
|
|
Packit Service |
b3514a |
* Pull an incoming bio off the queue.
|
|
Packit Service |
b3514a |
*
|
|
Packit Service |
b3514a |
* The arrival time returned may be incorrect if multiple bios were saved, as
|
|
Packit Service |
b3514a |
* there is no per-bio storage used, only one saved arrival time for the whole
|
|
Packit Service |
b3514a |
* queue.
|
|
Packit Service |
b3514a |
*
|
|
Packit Service |
b3514a |
* @param [in] queue The incoming-bio queue
|
|
Packit Service |
b3514a |
* @param [out] arrivalTime The arrival time to use for this bio
|
|
Packit Service |
b3514a |
*
|
|
Packit Service |
b3514a |
* @return a BIO pointer, or NULL if none were queued
|
|
Packit Service |
b3514a |
**/
|
|
Packit Service |
b3514a |
static inline BIO *pollDeadlockQueue(DeadlockQueue *queue,
|
|
Packit Service |
b3514a |
Jiffies *arrivalTime)
|
|
Packit Service |
b3514a |
{
|
|
Packit Service |
b3514a |
spin_lock(&queue->lock);
|
|
Packit Service |
b3514a |
BIO *bio = bio_list_pop(&queue->list);
|
|
Packit Service |
b3514a |
if (unlikely(bio != NULL)) {
|
|
Packit Service |
b3514a |
*arrivalTime = queue->arrivalTime;
|
|
Packit Service |
b3514a |
}
|
|
Packit Service |
b3514a |
spin_unlock(&queue->lock);
|
|
Packit Service |
b3514a |
return bio;
|
|
Packit Service |
b3514a |
}
|
|
Packit Service |
b3514a |
|
|
Packit Service |
b3514a |
#endif // DEADLOCK_QUEUE_H
|