/*
* Copyright (c) 2020 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/workQueueSysfs.c#1 $
*/
#include "workQueueSysfs.h"
#include <linux/kobject.h>
#include "logger.h"
#include "memoryAlloc.h"
#include "workQueueInternals.h"
typedef struct workQueueAttribute {
struct attribute attr;
ssize_t (*show)(const KvdoWorkQueue *queue, char *buf);
ssize_t (*store)(KvdoWorkQueue *queue, const char *buf, size_t length);
} WorkQueueAttribute;
/**********************************************************************/
static ssize_t nameShow(const KvdoWorkQueue *queue, char *buf)
{
return sprintf(buf, "%s\n", queue->name);
}
/**********************************************************************/
static ssize_t pidShow(const KvdoWorkQueue *queue, char *buf)
{
return sprintf(buf, "%ld\n",
(long) atomic_read(&asConstSimpleWorkQueue(queue)->threadID));
}
/**********************************************************************/
static ssize_t timesShow(const KvdoWorkQueue *queue, char *buf)
{
return formatRunTimeStats(&asConstSimpleWorkQueue(queue)->stats, buf);
}
/**********************************************************************/
static ssize_t typeShow(const KvdoWorkQueue *queue, char *buf)
{
strcpy(buf, queue->roundRobinMode ? "round-robin\n" : "simple\n");
return strlen(buf);
}
/**********************************************************************/
static ssize_t workFunctionsShow(const KvdoWorkQueue *queue, char *buf)
{
const SimpleWorkQueue *simpleQueue = asConstSimpleWorkQueue(queue);
return formatWorkItemStats(&simpleQueue->stats.workItemStats, buf,
PAGE_SIZE);
}
/**********************************************************************/
static WorkQueueAttribute nameAttr = {
.attr = { .name = "name", .mode = 0444, },
.show = nameShow,
};
/**********************************************************************/
static WorkQueueAttribute pidAttr = {
.attr = { .name = "pid", .mode = 0444, },
.show = pidShow,
};
/**********************************************************************/
static WorkQueueAttribute timesAttr = {
.attr = { .name = "times", .mode = 0444 },
.show = timesShow,
};
/**********************************************************************/
static WorkQueueAttribute typeAttr = {
.attr = { .name = "type", .mode = 0444, },
.show = typeShow,
};
/**********************************************************************/
static WorkQueueAttribute workFunctionsAttr = {
.attr = { .name = "work_functions", .mode = 0444, },
.show = workFunctionsShow,
};
/**********************************************************************/
static struct attribute *simpleWorkQueueAttrs[] = {
&nameAttr.attr,
&pidAttr.attr,
×Attr.attr,
&typeAttr.attr,
&workFunctionsAttr.attr,
NULL,
};
/**********************************************************************/
static struct attribute *roundRobinWorkQueueAttrs[] = {
&nameAttr.attr,
&typeAttr.attr,
NULL,
};
/**********************************************************************/
static ssize_t workQueueAttrShow(struct kobject *kobj,
struct attribute *attr,
char *buf)
{
WorkQueueAttribute *wqAttr = container_of(attr, WorkQueueAttribute, attr);
if (wqAttr->show == NULL) {
return -EINVAL;
}
KvdoWorkQueue *queue = container_of(kobj, KvdoWorkQueue, kobj);
return wqAttr->show(queue, buf);
}
/**********************************************************************/
static ssize_t workQueueAttrStore(struct kobject *kobj,
struct attribute *attr,
const char *buf,
size_t length)
{
WorkQueueAttribute *wqAttr = container_of(attr, WorkQueueAttribute, attr);
if (wqAttr->store == NULL) {
return -EINVAL;
}
KvdoWorkQueue *queue = container_of(kobj, KvdoWorkQueue, kobj);
return wqAttr->store(queue, buf, length);
}
/**********************************************************************/
static struct sysfs_ops workQueueSysfsOps = {
.show = workQueueAttrShow,
.store = workQueueAttrStore,
};
/**********************************************************************/
static void workQueueRelease(struct kobject *kobj)
{
KvdoWorkQueue *queue = container_of(kobj, KvdoWorkQueue, kobj);
FREE(queue->name);
if (queue->roundRobinMode) {
FREE(asRoundRobinWorkQueue(queue));
} else {
FREE(asSimpleWorkQueue(queue));
}
}
/**********************************************************************/
struct kobj_type simpleWorkQueueKobjType = {
.default_attrs = simpleWorkQueueAttrs,
.release = workQueueRelease,
.sysfs_ops = &workQueueSysfsOps,
};
/**********************************************************************/
struct kobj_type roundRobinWorkQueueKobjType = {
.default_attrs = roundRobinWorkQueueAttrs,
.release = workQueueRelease,
.sysfs_ops = &workQueueSysfsOps,
};