On Thu, 16 Sep 2010 16:37:35 -0700 Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> wrote: > On Wed, 01 Sep 2010 23:26:01 +0900 > Naohiro Aota <naota@xxxxxxxxx> wrote: > > > The idr_pre_get() kernel-doc says "This function should be called > > prior to locking and calling the idr_get_new* functions.", but the > > idr_pre_get() calling in bsg_register_queue() is put inside > > mutex_lock(). Let's fix it. > > > > The idr_pre_get() kerneldoc is wrong. Or at least, misleading. Ah, thanks a lot. As usual, seems that there are few reliable documents in kernel. > The way this all works is that we precharge the tree via idr_pre_get() > and we do this outside locks so we can use GFP_KERNEL. Then we take > the lock (a spinlock!) and then try to add an element to the tree, > which will consume objects from the pool which was prefilled by > idr_pre_get(). > > There's an obvious race here where someone else can get in and steal > objects from the prefilled pool. We can fix that with a retry loop: > > > again: > if (idr_pre_get(..., GFP_KERNEL) == NULL) > return -ENOMEM; /* We're really out-of-memory */ > spin_lock(lock); > if (idr_get_new(...) == -EAGAIN) { > spin_unlock(lock); > goto again; /* Someone stole our preallocation! */ > } > ... > > this way we avoid the false -ENOMEM which the race would have caused. > We only declare -ENOMEM when we're REALLY out of memory. Looks like there are many misuses idr_pre_get and idr_get_new; some even calls idr_get_new without any lock (e.g. blk_alloc_devt). -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html