Skip to content

Commit 15fc60c

Browse files
LuBaolujoergroedel
authored andcommitted
iommu: Merge iopf_device_param into iommu_fault_param
The struct dev_iommu contains two pointers, fault_param and iopf_param. The fault_param pointer points to a data structure that is used to store pending faults that are awaiting responses. The iopf_param pointer points to a data structure that is used to store partial faults that are part of a Page Request Group. The fault_param and iopf_param pointers are essentially duplicate. This causes memory waste. Merge the iopf_device_param pointer into the iommu_fault_param pointer to consolidate the code and save memory. The consolidated pointer would be allocated on demand when the device driver enables the iopf on device, and would be freed after iopf is disabled. Signed-off-by: Lu Baolu <[email protected]> Reviewed-by: Jason Gunthorpe <[email protected]> Reviewed-by: Kevin Tian <[email protected]> Tested-by: Yan Zhao <[email protected]> Tested-by: Longfang Liu <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 8b32a3b commit 15fc60c

File tree

3 files changed

+72
-90
lines changed

3 files changed

+72
-90
lines changed

drivers/iommu/io-pgfault.c

Lines changed: 52 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,6 @@ struct iopf_queue {
2525
struct mutex lock;
2626
};
2727

28-
/**
29-
* struct iopf_device_param - IO Page Fault data attached to a device
30-
* @dev: the device that owns this param
31-
* @queue: IOPF queue
32-
* @queue_list: index into queue->devices
33-
* @partial: faults that are part of a Page Request Group for which the last
34-
* request hasn't been submitted yet.
35-
*/
36-
struct iopf_device_param {
37-
struct device *dev;
38-
struct iopf_queue *queue;
39-
struct list_head queue_list;
40-
struct list_head partial;
41-
};
42-
4328
struct iopf_fault {
4429
struct iommu_fault fault;
4530
struct list_head list;
@@ -144,7 +129,7 @@ int iommu_queue_iopf(struct iommu_fault *fault, void *cookie)
144129
int ret;
145130
struct iopf_group *group;
146131
struct iopf_fault *iopf, *next;
147-
struct iopf_device_param *iopf_param;
132+
struct iommu_fault_param *iopf_param;
148133

149134
struct device *dev = cookie;
150135
struct dev_iommu *param = dev->iommu;
@@ -159,7 +144,7 @@ int iommu_queue_iopf(struct iommu_fault *fault, void *cookie)
159144
* As long as we're holding param->lock, the queue can't be unlinked
160145
* from the device and therefore cannot disappear.
161146
*/
162-
iopf_param = param->iopf_param;
147+
iopf_param = param->fault_param;
163148
if (!iopf_param)
164149
return -ENODEV;
165150

@@ -229,14 +214,14 @@ EXPORT_SYMBOL_GPL(iommu_queue_iopf);
229214
int iopf_queue_flush_dev(struct device *dev)
230215
{
231216
int ret = 0;
232-
struct iopf_device_param *iopf_param;
217+
struct iommu_fault_param *iopf_param;
233218
struct dev_iommu *param = dev->iommu;
234219

235220
if (!param)
236221
return -ENODEV;
237222

238223
mutex_lock(&param->lock);
239-
iopf_param = param->iopf_param;
224+
iopf_param = param->fault_param;
240225
if (iopf_param)
241226
flush_workqueue(iopf_param->queue->wq);
242227
else
@@ -260,7 +245,7 @@ EXPORT_SYMBOL_GPL(iopf_queue_flush_dev);
260245
int iopf_queue_discard_partial(struct iopf_queue *queue)
261246
{
262247
struct iopf_fault *iopf, *next;
263-
struct iopf_device_param *iopf_param;
248+
struct iommu_fault_param *iopf_param;
264249

265250
if (!queue)
266251
return -EINVAL;
@@ -287,34 +272,36 @@ EXPORT_SYMBOL_GPL(iopf_queue_discard_partial);
287272
*/
288273
int iopf_queue_add_device(struct iopf_queue *queue, struct device *dev)
289274
{
290-
int ret = -EBUSY;
291-
struct iopf_device_param *iopf_param;
275+
int ret = 0;
292276
struct dev_iommu *param = dev->iommu;
293-
294-
if (!param)
295-
return -ENODEV;
296-
297-
iopf_param = kzalloc(sizeof(*iopf_param), GFP_KERNEL);
298-
if (!iopf_param)
299-
return -ENOMEM;
300-
301-
INIT_LIST_HEAD(&iopf_param->partial);
302-
iopf_param->queue = queue;
303-
iopf_param->dev = dev;
277+
struct iommu_fault_param *fault_param;
304278

305279
mutex_lock(&queue->lock);
306280
mutex_lock(&param->lock);
307-
if (!param->iopf_param) {
308-
list_add(&iopf_param->queue_list, &queue->devices);
309-
param->iopf_param = iopf_param;
310-
ret = 0;
281+
if (param->fault_param) {
282+
ret = -EBUSY;
283+
goto done_unlock;
311284
}
285+
286+
fault_param = kzalloc(sizeof(*fault_param), GFP_KERNEL);
287+
if (!fault_param) {
288+
ret = -ENOMEM;
289+
goto done_unlock;
290+
}
291+
292+
mutex_init(&fault_param->lock);
293+
INIT_LIST_HEAD(&fault_param->faults);
294+
INIT_LIST_HEAD(&fault_param->partial);
295+
fault_param->dev = dev;
296+
list_add(&fault_param->queue_list, &queue->devices);
297+
fault_param->queue = queue;
298+
299+
param->fault_param = fault_param;
300+
301+
done_unlock:
312302
mutex_unlock(&param->lock);
313303
mutex_unlock(&queue->lock);
314304

315-
if (ret)
316-
kfree(iopf_param);
317-
318305
return ret;
319306
}
320307
EXPORT_SYMBOL_GPL(iopf_queue_add_device);
@@ -330,34 +317,41 @@ EXPORT_SYMBOL_GPL(iopf_queue_add_device);
330317
*/
331318
int iopf_queue_remove_device(struct iopf_queue *queue, struct device *dev)
332319
{
333-
int ret = -EINVAL;
320+
int ret = 0;
334321
struct iopf_fault *iopf, *next;
335-
struct iopf_device_param *iopf_param;
336322
struct dev_iommu *param = dev->iommu;
337-
338-
if (!param || !queue)
339-
return -EINVAL;
323+
struct iommu_fault_param *fault_param = param->fault_param;
340324

341325
mutex_lock(&queue->lock);
342326
mutex_lock(&param->lock);
343-
iopf_param = param->iopf_param;
344-
if (iopf_param && iopf_param->queue == queue) {
345-
list_del(&iopf_param->queue_list);
346-
param->iopf_param = NULL;
347-
ret = 0;
327+
if (!fault_param) {
328+
ret = -ENODEV;
329+
goto unlock;
348330
}
349-
mutex_unlock(&param->lock);
350-
mutex_unlock(&queue->lock);
351-
if (ret)
352-
return ret;
331+
332+
if (fault_param->queue != queue) {
333+
ret = -EINVAL;
334+
goto unlock;
335+
}
336+
337+
if (!list_empty(&fault_param->faults)) {
338+
ret = -EBUSY;
339+
goto unlock;
340+
}
341+
342+
list_del(&fault_param->queue_list);
353343

354344
/* Just in case some faults are still stuck */
355-
list_for_each_entry_safe(iopf, next, &iopf_param->partial, list)
345+
list_for_each_entry_safe(iopf, next, &fault_param->partial, list)
356346
kfree(iopf);
357347

358-
kfree(iopf_param);
348+
param->fault_param = NULL;
349+
kfree(fault_param);
350+
unlock:
351+
mutex_unlock(&param->lock);
352+
mutex_unlock(&queue->lock);
359353

360-
return 0;
354+
return ret;
361355
}
362356
EXPORT_SYMBOL_GPL(iopf_queue_remove_device);
363357

@@ -403,7 +397,7 @@ EXPORT_SYMBOL_GPL(iopf_queue_alloc);
403397
*/
404398
void iopf_queue_free(struct iopf_queue *queue)
405399
{
406-
struct iopf_device_param *iopf_param, *next;
400+
struct iommu_fault_param *iopf_param, *next;
407401

408402
if (!queue)
409403
return;

drivers/iommu/iommu.c

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,27 +1355,18 @@ int iommu_register_device_fault_handler(struct device *dev,
13551355
struct dev_iommu *param = dev->iommu;
13561356
int ret = 0;
13571357

1358-
if (!param)
1358+
if (!param || !param->fault_param)
13591359
return -EINVAL;
13601360

13611361
mutex_lock(&param->lock);
13621362
/* Only allow one fault handler registered for each device */
1363-
if (param->fault_param) {
1363+
if (param->fault_param->handler) {
13641364
ret = -EBUSY;
13651365
goto done_unlock;
13661366
}
13671367

1368-
get_device(dev);
1369-
param->fault_param = kzalloc(sizeof(*param->fault_param), GFP_KERNEL);
1370-
if (!param->fault_param) {
1371-
put_device(dev);
1372-
ret = -ENOMEM;
1373-
goto done_unlock;
1374-
}
13751368
param->fault_param->handler = handler;
13761369
param->fault_param->data = data;
1377-
mutex_init(&param->fault_param->lock);
1378-
INIT_LIST_HEAD(&param->fault_param->faults);
13791370

13801371
done_unlock:
13811372
mutex_unlock(&param->lock);
@@ -1396,29 +1387,16 @@ EXPORT_SYMBOL_GPL(iommu_register_device_fault_handler);
13961387
int iommu_unregister_device_fault_handler(struct device *dev)
13971388
{
13981389
struct dev_iommu *param = dev->iommu;
1399-
int ret = 0;
14001390

1401-
if (!param)
1391+
if (!param || !param->fault_param)
14021392
return -EINVAL;
14031393

14041394
mutex_lock(&param->lock);
1405-
1406-
if (!param->fault_param)
1407-
goto unlock;
1408-
1409-
/* we cannot unregister handler if there are pending faults */
1410-
if (!list_empty(&param->fault_param->faults)) {
1411-
ret = -EBUSY;
1412-
goto unlock;
1413-
}
1414-
1415-
kfree(param->fault_param);
1416-
param->fault_param = NULL;
1417-
put_device(dev);
1418-
unlock:
1395+
param->fault_param->handler = NULL;
1396+
param->fault_param->data = NULL;
14191397
mutex_unlock(&param->lock);
14201398

1421-
return ret;
1399+
return 0;
14221400
}
14231401
EXPORT_SYMBOL_GPL(iommu_unregister_device_fault_handler);
14241402

include/linux/iommu.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ struct notifier_block;
4242
struct iommu_sva;
4343
struct iommu_fault_event;
4444
struct iommu_dma_cookie;
45+
struct iopf_queue;
4546

4647
#define IOMMU_FAULT_PERM_READ (1 << 0) /* read */
4748
#define IOMMU_FAULT_PERM_WRITE (1 << 1) /* write */
@@ -672,21 +673,31 @@ struct iommu_fault_event {
672673
* struct iommu_fault_param - per-device IOMMU fault data
673674
* @handler: Callback function to handle IOMMU faults at device level
674675
* @data: handler private data
675-
* @faults: holds the pending faults which needs response
676676
* @lock: protect pending faults list
677+
* @dev: the device that owns this param
678+
* @queue: IOPF queue
679+
* @queue_list: index into queue->devices
680+
* @partial: faults that are part of a Page Request Group for which the last
681+
* request hasn't been submitted yet.
682+
* @faults: holds the pending faults which need response
677683
*/
678684
struct iommu_fault_param {
679685
iommu_dev_fault_handler_t handler;
680686
void *data;
681-
struct list_head faults;
682687
struct mutex lock;
688+
689+
struct device *dev;
690+
struct iopf_queue *queue;
691+
struct list_head queue_list;
692+
693+
struct list_head partial;
694+
struct list_head faults;
683695
};
684696

685697
/**
686698
* struct dev_iommu - Collection of per-device IOMMU data
687699
*
688700
* @fault_param: IOMMU detected device fault reporting data
689-
* @iopf_param: I/O Page Fault queue and data
690701
* @fwspec: IOMMU fwspec data
691702
* @iommu_dev: IOMMU device this device is linked to
692703
* @priv: IOMMU Driver private data
@@ -702,7 +713,6 @@ struct iommu_fault_param {
702713
struct dev_iommu {
703714
struct mutex lock;
704715
struct iommu_fault_param *fault_param;
705-
struct iopf_device_param *iopf_param;
706716
struct iommu_fwspec *fwspec;
707717
struct iommu_device *iommu_dev;
708718
void *priv;

0 commit comments

Comments
 (0)