Skip to content

Commit

Permalink
iommu/amd: Fix amd_iommu_free_device()
Browse files Browse the repository at this point in the history
put_device_state_wait() doesn't loop on the condition and a spurious
wakeup will have it free the device state even though there might still
be references out to it.

Fix this by using 'normal' wait primitives.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
  • Loading branch information
Peter Zijlstra authored and Joerg Roedel committed Feb 4, 2015
1 parent e36f014 commit 91f65fa
Showing 1 changed file with 7 additions and 13 deletions.
20 changes: 7 additions & 13 deletions drivers/iommu/amd_iommu_v2.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,18 +151,6 @@ static void put_device_state(struct device_state *dev_state)
wake_up(&dev_state->wq);
}

static void put_device_state_wait(struct device_state *dev_state)
{
DEFINE_WAIT(wait);

prepare_to_wait(&dev_state->wq, &wait, TASK_UNINTERRUPTIBLE);
if (!atomic_dec_and_test(&dev_state->count))
schedule();
finish_wait(&dev_state->wq, &wait);

free_device_state(dev_state);
}

/* Must be called under dev_state->lock */
static struct pasid_state **__get_pasid_state_ptr(struct device_state *dev_state,
int pasid, bool alloc)
Expand Down Expand Up @@ -851,7 +839,13 @@ void amd_iommu_free_device(struct pci_dev *pdev)
/* Get rid of any remaining pasid states */
free_pasid_states(dev_state);

put_device_state_wait(dev_state);
put_device_state(dev_state);
/*
* Wait until the last reference is dropped before freeing
* the device state.
*/
wait_event(dev_state->wq, !atomic_read(&dev_state->count));
free_device_state(dev_state);
}
EXPORT_SYMBOL(amd_iommu_free_device);

Expand Down

0 comments on commit 91f65fa

Please sign in to comment.