aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/amd_iommu_v2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iommu/amd_iommu_v2.c')
-rw-r--r--drivers/iommu/amd_iommu_v2.c35
1 files changed, 11 insertions, 24 deletions
diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c
index 90f70d0e1141..6d5a5c44453b 100644
--- a/drivers/iommu/amd_iommu_v2.c
+++ b/drivers/iommu/amd_iommu_v2.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) 2010-2012 Advanced Micro Devices, Inc. 2 * Copyright (C) 2010-2012 Advanced Micro Devices, Inc.
3 * Author: Joerg Roedel <joerg.roedel@amd.com> 3 * Author: Joerg Roedel <jroedel@suse.de>
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published 6 * under the terms of the GNU General Public License version 2 as published
@@ -31,7 +31,7 @@
31#include "amd_iommu_proto.h" 31#include "amd_iommu_proto.h"
32 32
33MODULE_LICENSE("GPL v2"); 33MODULE_LICENSE("GPL v2");
34MODULE_AUTHOR("Joerg Roedel <joerg.roedel@amd.com>"); 34MODULE_AUTHOR("Joerg Roedel <jroedel@suse.de>");
35 35
36#define MAX_DEVICES 0x10000 36#define MAX_DEVICES 0x10000
37#define PRI_QUEUE_SIZE 512 37#define PRI_QUEUE_SIZE 512
@@ -151,18 +151,6 @@ static void put_device_state(struct device_state *dev_state)
151 wake_up(&dev_state->wq); 151 wake_up(&dev_state->wq);
152} 152}
153 153
154static void put_device_state_wait(struct device_state *dev_state)
155{
156 DEFINE_WAIT(wait);
157
158 prepare_to_wait(&dev_state->wq, &wait, TASK_UNINTERRUPTIBLE);
159 if (!atomic_dec_and_test(&dev_state->count))
160 schedule();
161 finish_wait(&dev_state->wq, &wait);
162
163 free_device_state(dev_state);
164}
165
166/* Must be called under dev_state->lock */ 154/* Must be called under dev_state->lock */
167static struct pasid_state **__get_pasid_state_ptr(struct device_state *dev_state, 155static struct pasid_state **__get_pasid_state_ptr(struct device_state *dev_state,
168 int pasid, bool alloc) 156 int pasid, bool alloc)
@@ -278,14 +266,7 @@ static void put_pasid_state(struct pasid_state *pasid_state)
278 266
279static void put_pasid_state_wait(struct pasid_state *pasid_state) 267static void put_pasid_state_wait(struct pasid_state *pasid_state)
280{ 268{
281 DEFINE_WAIT(wait); 269 wait_event(pasid_state->wq, !atomic_read(&pasid_state->count));
282
283 prepare_to_wait(&pasid_state->wq, &wait, TASK_UNINTERRUPTIBLE);
284
285 if (!atomic_dec_and_test(&pasid_state->count))
286 schedule();
287
288 finish_wait(&pasid_state->wq, &wait);
289 free_pasid_state(pasid_state); 270 free_pasid_state(pasid_state);
290} 271}
291 272
@@ -851,7 +832,13 @@ void amd_iommu_free_device(struct pci_dev *pdev)
851 /* Get rid of any remaining pasid states */ 832 /* Get rid of any remaining pasid states */
852 free_pasid_states(dev_state); 833 free_pasid_states(dev_state);
853 834
854 put_device_state_wait(dev_state); 835 put_device_state(dev_state);
836 /*
837 * Wait until the last reference is dropped before freeing
838 * the device state.
839 */
840 wait_event(dev_state->wq, !atomic_read(&dev_state->count));
841 free_device_state(dev_state);
855} 842}
856EXPORT_SYMBOL(amd_iommu_free_device); 843EXPORT_SYMBOL(amd_iommu_free_device);
857 844
@@ -921,7 +908,7 @@ static int __init amd_iommu_v2_init(void)
921{ 908{
922 int ret; 909 int ret;
923 910
924 pr_info("AMD IOMMUv2 driver by Joerg Roedel <joerg.roedel@amd.com>\n"); 911 pr_info("AMD IOMMUv2 driver by Joerg Roedel <jroedel@suse.de>\n");
925 912
926 if (!amd_iommu_v2_supported()) { 913 if (!amd_iommu_v2_supported()) {
927 pr_info("AMD IOMMUv2 functionality not available on this system\n"); 914 pr_info("AMD IOMMUv2 functionality not available on this system\n");