/* * 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 #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, };