Skip to content

Commit 353dd72

Browse files
davem330gregkh
authored andcommitted
irda: Fix lockdep annotations in hashbin_delete().
[ Upstream commit 4c03b862b12f980456f9de92db6d508a4999b788 ] A nested lock depth was added to the hasbin_delete() code but it doesn't actually work some well and results in tons of lockdep splats. Fix the code instead to properly drop the lock around the operation and just keep peeking the head of the hashbin queue. Reported-by: Dmitry Vyukov <dvyukov@google.com> Tested-by: Dmitry Vyukov <dvyukov@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent a95df07 commit 353dd72

1 file changed

Lines changed: 16 additions & 18 deletions

File tree

net/irda/irqueue.c

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -383,9 +383,6 @@ EXPORT_SYMBOL(hashbin_new);
383383
* for deallocating this structure if it's complex. If not the user can
384384
* just supply kfree, which should take care of the job.
385385
*/
386-
#ifdef CONFIG_LOCKDEP
387-
static int hashbin_lock_depth = 0;
388-
#endif
389386
int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func)
390387
{
391388
irda_queue_t* queue;
@@ -396,22 +393,27 @@ int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func)
396393
IRDA_ASSERT(hashbin->magic == HB_MAGIC, return -1;);
397394

398395
/* Synchronize */
399-
if ( hashbin->hb_type & HB_LOCK ) {
400-
spin_lock_irqsave_nested(&hashbin->hb_spinlock, flags,
401-
hashbin_lock_depth++);
402-
}
396+
if (hashbin->hb_type & HB_LOCK)
397+
spin_lock_irqsave(&hashbin->hb_spinlock, flags);
403398

404399
/*
405400
* Free the entries in the hashbin, TODO: use hashbin_clear when
406401
* it has been shown to work
407402
*/
408403
for (i = 0; i < HASHBIN_SIZE; i ++ ) {
409-
queue = dequeue_first((irda_queue_t**) &hashbin->hb_queue[i]);
410-
while (queue ) {
411-
if (free_func)
412-
(*free_func)(queue);
413-
queue = dequeue_first(
414-
(irda_queue_t**) &hashbin->hb_queue[i]);
404+
while (1) {
405+
queue = dequeue_first((irda_queue_t**) &hashbin->hb_queue[i]);
406+
407+
if (!queue)
408+
break;
409+
410+
if (free_func) {
411+
if (hashbin->hb_type & HB_LOCK)
412+
spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);
413+
free_func(queue);
414+
if (hashbin->hb_type & HB_LOCK)
415+
spin_lock_irqsave(&hashbin->hb_spinlock, flags);
416+
}
415417
}
416418
}
417419

@@ -420,12 +422,8 @@ int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func)
420422
hashbin->magic = ~HB_MAGIC;
421423

422424
/* Release lock */
423-
if ( hashbin->hb_type & HB_LOCK) {
425+
if (hashbin->hb_type & HB_LOCK)
424426
spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);
425-
#ifdef CONFIG_LOCKDEP
426-
hashbin_lock_depth--;
427-
#endif
428-
}
429427

430428
/*
431429
* Free the hashbin structure

0 commit comments

Comments
 (0)