On Wed, Jun 01, 2022 at 05:18:24PM -0400, Waiman Long wrote:
@@ -59,6 +59,57 @@ static struct workqueue_struct *blkcg_punt_bio_wq;Can you please add why we want all entries to have non-NULL next?
#define BLKG_DESTROY_BATCH_SIZE 64
+/*
+ * lnode.next of the last entry in a lockless list is NULL. To make it
+ * always non-NULL for lnode's, a sentinel node has to be put at the
+ * end of the lockless list. So all the percpu lhead's are initialized
+ * to point to that sentinel node.
+ */
+static inline bool blkcg_llist_empty(struct llist_head *lhead)It's not a strong opinion but I'm not too fond of using inlines to mark
+{
+ return lhead->first == &llist_last;
+}
+
+static inline void init_blkcg_llists(struct blkcg *blkcg)
+{
+ int cpu;
+
+ for_each_possible_cpu(cpu)
+ per_cpu_ptr(blkcg->lhead, cpu)->first = &llist_last;
+}
+
+static inline struct llist_node *
+fetch_delete_blkcg_llist(struct llist_head *lhead)
+{
+ return xchg(&lhead->first, &llist_last);
+}
+
+static inline struct llist_node *
+fetch_delete_lnode_next(struct llist_node *lnode)
+{
+ struct llist_node *next = READ_ONCE(lnode->next);
+ struct blkcg_gq *blkg = llist_entry(lnode, struct blkg_iostat_set,
+ lnode)->blkg;
+
+ WRITE_ONCE(lnode->next, NULL);
+ percpu_ref_put(&blkg->refcnt);
+ return next;
+}
trivial functions. The compiler should be able to make these decisions,
right?
Other than the above two bikesheddings,
Acked-by: Tejun Heo <tj@xxxxxxxxxx>
Thanks.