Skip to content

Commit

Permalink
Fix accounting error for pending sync reads in zpool iostat
Browse files Browse the repository at this point in the history
Currently vdev_queue_class_length is responsible for checking how long
the queue length is, however, it doesn't check the length when a list
is used, rather it just returns whether it is empty or not. This has
been changed to now check the list length. In order to facilitate
easier accounting, a list length variable has been added to the
list_t struct to keep track of the current list length.

Signed-off-by: MigeljanImeri <ImeriMigel@gmail.com>
  • Loading branch information
MigeljanImeri committed Nov 1, 2023
1 parent 57b4098 commit ecb9c79
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 3 deletions.
1 change: 1 addition & 0 deletions include/os/freebsd/spl/sys/list.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ void *list_tail(list_t *);
void *list_next(list_t *, void *);
void *list_prev(list_t *, void *);
int list_is_empty(list_t *);
int list_length(list_t *);

void list_link_init(list_node_t *);
void list_link_replace(list_node_t *, list_node_t *);
Expand Down
23 changes: 21 additions & 2 deletions include/os/linux/spl/sys/list.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ typedef struct list_head list_node_t;
typedef struct list {
size_t list_size;
size_t list_offset;
uint32_t list_length;
list_node_t list_head;
} list_t;

Expand All @@ -62,6 +63,12 @@ list_is_empty(list_t *list)
return (list_empty(&list->list_head));
}

static inline int
list_length(list_t *list)
{
return (list->list_length);
}

static inline void
list_link_init(list_node_t *node)
{
Expand All @@ -74,6 +81,7 @@ list_create(list_t *list, size_t size, size_t offset)
{
list->list_size = size;
list->list_offset = offset;
list->list_length = 0;
INIT_LIST_HEAD(&list->list_head);
}

Expand All @@ -86,12 +94,14 @@ list_destroy(list_t *list)
static inline void
list_insert_head(list_t *list, void *object)
{
list->list_length++;
list_add(list_d2l(list, object), &list->list_head);
}

static inline void
list_insert_tail(list_t *list, void *object)
{
list->list_length++;
list_add_tail(list_d2l(list, object), &list->list_head);
}

Expand All @@ -100,28 +110,34 @@ list_insert_after(list_t *list, void *object, void *nobject)
{
if (object == NULL)
list_insert_head(list, nobject);
else
else {
list->list_length++;
list_add(list_d2l(list, nobject), list_d2l(list, object));
}
}

static inline void
list_insert_before(list_t *list, void *object, void *nobject)
{
if (object == NULL)
list_insert_tail(list, nobject);
else
else {
list->list_length++;
list_add_tail(list_d2l(list, nobject), list_d2l(list, object));
}
}

static inline void
list_remove(list_t *list, void *object)
{
list->list_length--;
list_del(list_d2l(list, object));
}

static inline void *
list_remove_head(list_t *list)
{
list->list_length--;
list_node_t *head = list->list_head.next;
if (head == &list->list_head)
return (NULL);
Expand All @@ -133,6 +149,7 @@ list_remove_head(list_t *list)
static inline void *
list_remove_tail(list_t *list)
{
list->list_length--;
list_node_t *tail = list->list_head.prev;
if (tail == &list->list_head)
return (NULL);
Expand Down Expand Up @@ -191,6 +208,8 @@ list_link_active(list_node_t *node)
static inline void
spl_list_move_tail(list_t *dst, list_t *src)
{
dst->list_length += src->list_length;
src->list_length = 0;
list_splice_init(&src->list_head, dst->list_head.prev);
}

Expand Down
1 change: 1 addition & 0 deletions lib/libspl/include/sys/list.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ void *list_tail(list_t *);
void *list_next(list_t *, void *);
void *list_prev(list_t *, void *);
int list_is_empty(list_t *);
int list_length(list_t *);

void list_link_init(list_node_t *);
void list_link_replace(list_node_t *, list_node_t *);
Expand Down
1 change: 1 addition & 0 deletions lib/libspl/include/sys/list_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ struct list_node {
struct list {
size_t list_size;
size_t list_offset;
uint32_t list_length;
struct list_node list_head;
};

Expand Down
18 changes: 18 additions & 0 deletions lib/libspl/list.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ list_create(list_t *list, size_t size, size_t offset)

list->list_size = size;
list->list_offset = offset;
list->list_length = 0;
list->list_head.next = list->list_head.prev = &list->list_head;
}

Expand All @@ -88,6 +89,7 @@ list_insert_after(list_t *list, void *object, void *nobject)
if (object == NULL) {
list_insert_head(list, nobject);
} else {
list->list_length++;
list_node_t *lold = list_d2l(list, object);
list_insert_after_node(list, lold, nobject);
}
Expand All @@ -99,6 +101,7 @@ list_insert_before(list_t *list, void *object, void *nobject)
if (object == NULL) {
list_insert_tail(list, nobject);
} else {
list->list_length++;
list_node_t *lold = list_d2l(list, object);
list_insert_before_node(list, lold, nobject);
}
Expand All @@ -107,20 +110,23 @@ list_insert_before(list_t *list, void *object, void *nobject)
void
list_insert_head(list_t *list, void *object)
{
list->list_length++;
list_node_t *lold = &list->list_head;
list_insert_after_node(list, lold, object);
}

void
list_insert_tail(list_t *list, void *object)
{
list->list_length++;
list_node_t *lold = &list->list_head;
list_insert_before_node(list, lold, object);
}

void
list_remove(list_t *list, void *object)
{
list->list_length--;
list_node_t *lold = list_d2l(list, object);
ASSERT(!list_empty(list));
ASSERT(lold->next != NULL);
Expand All @@ -130,6 +136,7 @@ list_remove(list_t *list, void *object)
void *
list_remove_head(list_t *list)
{
list->list_length--;
list_node_t *head = list->list_head.next;
if (head == &list->list_head)
return (NULL);
Expand All @@ -140,6 +147,7 @@ list_remove_head(list_t *list)
void *
list_remove_tail(list_t *list)
{
list->list_length--;
list_node_t *tail = list->list_head.prev;
if (tail == &list->list_head)
return (NULL);
Expand Down Expand Up @@ -200,13 +208,17 @@ list_move_tail(list_t *dst, list_t *src)
if (list_empty(src))
return;

dst->list_length += src->list_length;

dstnode->prev->next = srcnode->next;
srcnode->next->prev = dstnode->prev;
dstnode->prev = srcnode->prev;
srcnode->prev->next = dstnode;

/* empty src list */
srcnode->next = srcnode->prev = srcnode;

src->list_length = 0;
}

void
Expand Down Expand Up @@ -241,3 +253,9 @@ list_is_empty(list_t *list)
{
return (list_empty(list));
}

int
list_length(list_t *list)
{
return (list->list_length);
}
2 changes: 1 addition & 1 deletion module/zfs/vdev_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -1069,7 +1069,7 @@ vdev_queue_class_length(vdev_t *vd, zio_priority_t p)
{
vdev_queue_t *vq = &vd->vdev_queue;
if (vdev_queue_class_fifo(p))
return (list_is_empty(&vq->vq_class[p].vqc_list) == 0);
return (list_length(&vq->vq_class[p].vqc_list));
else
return (avl_numnodes(&vq->vq_class[p].vqc_tree));
}
Expand Down

0 comments on commit ecb9c79

Please sign in to comment.