On 03/11/2017 03:42 PM, Jens Axboe wrote: >> @@ -185,31 +187,53 @@ static struct blkcg_gq *blkg_create(struct blkcg *blkcg, >> goto err_free_blkg; >> } >> >> + if (drop_locks) { >> + spin_unlock_irq(q->queue_lock); >> + rcu_read_unlock(); >> + } > > I have a general dislike for code like that, where you conditionally > drop locks. And this one seems even worse, since the knowledge of > whether the locks should/could be dropped or not is embedded in the gfp > flags. Talked to Tejun about this as well, and we both agree that the splitting this into separate init/alloc paths would be much cleaner. I can't apply the current patch, sorry, it's just too ugly to live. >> +/** >> + * blkg_lookup_create - lookup blkg, try to create one if not there >> + * >> + * Performs an initial queue bypass check and then passes control to >> + * __blkg_lookup_create(). >> + */ >> +struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg, >> + struct request_queue *q, gfp_t gfp, >> + const struct blkcg_policy *pol) >> +{ >> + WARN_ON_ONCE(!rcu_read_lock_held()); >> + lockdep_assert_held(q->queue_lock); > > This seems problematic, as blkcg_bio_issue_check() calls with the rcu > read lock held. Brain fart, that part is fine. -- Jens Axboe