Skip to content

Commit ec0d642

Browse files
davejiangvinodkoul
authored andcommitted
dmaengine: idxd: embed irq_entry in idxd_wq struct
With irq_entry already being associated with the wq in a 1:1 relationship, embed the irq_entry in the idxd_wq struct and remove back pointers for idxe_wq and idxd_device. In the process of this work, clean up the interrupt handle assignment so that there's no decision to be made during submit call on where interrupt handle value comes from. Set the interrupt handle during irq request initialization time. irq_entry 0 is designated as special and is tied to the device itself. Signed-off-by: Dave Jiang <[email protected]> Link: https://lore.kernel.org/r/163942148362.2412839.12055447853311267866.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul <[email protected]>
1 parent 26e9baa commit ec0d642

File tree

6 files changed

+79
-99
lines changed

6 files changed

+79
-99
lines changed

drivers/dma/idxd/device.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@ static void idxd_wq_disable_cleanup(struct idxd_wq *wq);
2121
/* Interrupt control bits */
2222
void idxd_mask_msix_vector(struct idxd_device *idxd, int vec_id)
2323
{
24-
struct irq_data *data = irq_get_irq_data(idxd->irq_entries[vec_id].vector);
24+
struct idxd_irq_entry *ie;
25+
struct irq_data *data;
2526

27+
ie = idxd_get_ie(idxd, vec_id);
28+
data = irq_get_irq_data(ie->vector);
2629
pci_msi_mask_irq(data);
2730
}
2831

@@ -38,8 +41,11 @@ void idxd_mask_msix_vectors(struct idxd_device *idxd)
3841

3942
void idxd_unmask_msix_vector(struct idxd_device *idxd, int vec_id)
4043
{
41-
struct irq_data *data = irq_get_irq_data(idxd->irq_entries[vec_id].vector);
44+
struct idxd_irq_entry *ie;
45+
struct irq_data *data;
4246

47+
ie = idxd_get_ie(idxd, vec_id);
48+
data = irq_get_irq_data(ie->vector);
4349
pci_msi_unmask_irq(data);
4450
}
4551

@@ -1216,13 +1222,6 @@ int __drv_enable_wq(struct idxd_wq *wq)
12161222
goto err;
12171223
}
12181224

1219-
/*
1220-
* Device has 1 misc interrupt and N interrupts for descriptor completion. To
1221-
* assign WQ to interrupt, we will take the N+1 interrupt since vector 0 is
1222-
* for the misc interrupt.
1223-
*/
1224-
wq->ie = &idxd->irq_entries[wq->id + 1];
1225-
12261225
rc = idxd_wq_enable(wq);
12271226
if (rc < 0) {
12281227
dev_dbg(dev, "wq %d enabling failed: %d\n", wq->id, rc);
@@ -1273,7 +1272,6 @@ void __drv_disable_wq(struct idxd_wq *wq)
12731272
idxd_wq_drain(wq);
12741273
idxd_wq_reset(wq);
12751274

1276-
wq->ie = NULL;
12771275
wq->client_count = 0;
12781276
}
12791277

drivers/dma/idxd/idxd.h

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ extern struct idxd_device_driver idxd_user_drv;
7070

7171
#define INVALID_INT_HANDLE -1
7272
struct idxd_irq_entry {
73-
struct idxd_device *idxd;
7473
int id;
7574
int vector;
7675
struct llist_head pending_llist;
@@ -81,7 +80,6 @@ struct idxd_irq_entry {
8180
*/
8281
spinlock_t list_lock;
8382
int int_handle;
84-
struct idxd_wq *wq;
8583
ioasid_t pasid;
8684
};
8785

@@ -185,7 +183,7 @@ struct idxd_wq {
185183
struct wait_queue_head err_queue;
186184
struct idxd_device *idxd;
187185
int id;
188-
struct idxd_irq_entry *ie;
186+
struct idxd_irq_entry ie;
189187
enum idxd_wq_type type;
190188
struct idxd_group *group;
191189
int client_count;
@@ -266,6 +264,7 @@ struct idxd_device {
266264
int id;
267265
int major;
268266
u32 cmd_status;
267+
struct idxd_irq_entry ie; /* misc irq, msix 0 */
269268

270269
struct pci_dev *pdev;
271270
void __iomem *reg_base;
@@ -302,8 +301,6 @@ struct idxd_device {
302301

303302
union sw_err_reg sw_err;
304303
wait_queue_head_t cmd_waitq;
305-
int num_wq_irqs;
306-
struct idxd_irq_entry *irq_entries;
307304

308305
struct idxd_dma_dev *idxd_dma;
309306
struct workqueue_struct *wq;
@@ -395,6 +392,21 @@ static inline void idxd_dev_set_type(struct idxd_dev *idev, int type)
395392
idev->type = type;
396393
}
397394

395+
static inline struct idxd_irq_entry *idxd_get_ie(struct idxd_device *idxd, int idx)
396+
{
397+
return (idx == 0) ? &idxd->ie : &idxd->wqs[idx - 1]->ie;
398+
}
399+
400+
static inline struct idxd_wq *ie_to_wq(struct idxd_irq_entry *ie)
401+
{
402+
return container_of(ie, struct idxd_wq, ie);
403+
}
404+
405+
static inline struct idxd_device *ie_to_idxd(struct idxd_irq_entry *ie)
406+
{
407+
return container_of(ie, struct idxd_device, ie);
408+
}
409+
398410
extern struct bus_type dsa_bus_type;
399411

400412
extern bool support_enqcmd;

drivers/dma/idxd/init.c

Lines changed: 47 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
7272
{
7373
struct pci_dev *pdev = idxd->pdev;
7474
struct device *dev = &pdev->dev;
75-
struct idxd_irq_entry *irq_entry;
75+
struct idxd_irq_entry *ie;
7676
int i, msixcnt;
7777
int rc = 0;
7878

@@ -90,96 +90,74 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
9090
}
9191
dev_dbg(dev, "Enabled %d msix vectors\n", msixcnt);
9292

93-
/*
94-
* We implement 1 completion list per MSI-X entry except for
95-
* entry 0, which is for errors and others.
96-
*/
97-
idxd->irq_entries = kcalloc_node(msixcnt, sizeof(struct idxd_irq_entry),
98-
GFP_KERNEL, dev_to_node(dev));
99-
if (!idxd->irq_entries) {
100-
rc = -ENOMEM;
101-
goto err_irq_entries;
102-
}
103-
104-
for (i = 0; i < msixcnt; i++) {
105-
idxd->irq_entries[i].id = i;
106-
idxd->irq_entries[i].idxd = idxd;
107-
/*
108-
* Association of WQ should be assigned starting with irq_entry 1.
109-
* irq_entry 0 is for misc interrupts and has no wq association
110-
*/
111-
if (i > 0)
112-
idxd->irq_entries[i].wq = idxd->wqs[i - 1];
113-
idxd->irq_entries[i].vector = pci_irq_vector(pdev, i);
114-
idxd->irq_entries[i].int_handle = INVALID_INT_HANDLE;
115-
if (device_pasid_enabled(idxd) && i > 0)
116-
idxd->irq_entries[i].pasid = idxd->pasid;
117-
else
118-
idxd->irq_entries[i].pasid = INVALID_IOASID;
119-
spin_lock_init(&idxd->irq_entries[i].list_lock);
120-
}
121-
12293
idxd_msix_perm_setup(idxd);
12394

124-
irq_entry = &idxd->irq_entries[0];
125-
rc = request_threaded_irq(irq_entry->vector, NULL, idxd_misc_thread,
126-
0, "idxd-misc", irq_entry);
95+
ie = idxd_get_ie(idxd, 0);
96+
ie->vector = pci_irq_vector(pdev, 0);
97+
rc = request_threaded_irq(ie->vector, NULL, idxd_misc_thread, 0, "idxd-misc", ie);
12798
if (rc < 0) {
12899
dev_err(dev, "Failed to allocate misc interrupt.\n");
129100
goto err_misc_irq;
130101
}
131102

132-
dev_dbg(dev, "Allocated idxd-misc handler on msix vector %d\n", irq_entry->vector);
103+
dev_dbg(dev, "Allocated idxd-misc handler on msix vector %d\n", ie->vector);
133104

134-
/* first MSI-X entry is not for wq interrupts */
135-
idxd->num_wq_irqs = msixcnt - 1;
105+
for (i = 0; i < idxd->max_wqs; i++) {
106+
int msix_idx = i + 1;
107+
108+
ie = idxd_get_ie(idxd, msix_idx);
136109

137-
for (i = 1; i < msixcnt; i++) {
138-
irq_entry = &idxd->irq_entries[i];
110+
/* MSIX vector 0 special, wq irq entry starts at 1 */
111+
ie->id = msix_idx;
112+
ie->vector = pci_irq_vector(pdev, msix_idx);
113+
ie->int_handle = INVALID_INT_HANDLE;
114+
if (device_pasid_enabled(idxd) && i > 0)
115+
ie->pasid = idxd->pasid;
116+
else
117+
ie->pasid = INVALID_IOASID;
118+
spin_lock_init(&ie->list_lock);
119+
init_llist_head(&ie->pending_llist);
120+
INIT_LIST_HEAD(&ie->work_list);
139121

140-
init_llist_head(&idxd->irq_entries[i].pending_llist);
141-
INIT_LIST_HEAD(&idxd->irq_entries[i].work_list);
142-
rc = request_threaded_irq(irq_entry->vector, NULL,
143-
idxd_wq_thread, 0, "idxd-portal", irq_entry);
122+
rc = request_threaded_irq(ie->vector, NULL, idxd_wq_thread, 0, "idxd-portal", ie);
144123
if (rc < 0) {
145-
dev_err(dev, "Failed to allocate irq %d.\n", irq_entry->vector);
124+
dev_err(dev, "Failed to allocate irq %d.\n", ie->vector);
146125
goto err_wq_irqs;
147126
}
148127

149-
dev_dbg(dev, "Allocated idxd-msix %d for vector %d\n", i, irq_entry->vector);
128+
dev_dbg(dev, "Allocated idxd-msix %d for vector %d\n", i, ie->vector);
150129
if (idxd->request_int_handles) {
151-
rc = idxd_device_request_int_handle(idxd, i, &irq_entry->int_handle,
130+
rc = idxd_device_request_int_handle(idxd, i, &ie->int_handle,
152131
IDXD_IRQ_MSIX);
153132
if (rc < 0) {
154-
free_irq(irq_entry->vector, irq_entry);
133+
free_irq(ie->vector, ie);
155134
goto err_wq_irqs;
156135
}
157-
dev_dbg(dev, "int handle requested: %u\n", irq_entry->int_handle);
136+
dev_dbg(dev, "int handle requested: %u\n", ie->int_handle);
137+
} else {
138+
ie->int_handle = msix_idx;
158139
}
140+
159141
}
160142

161143
idxd_unmask_error_interrupts(idxd);
162144
return 0;
163145

164146
err_wq_irqs:
165147
while (--i >= 0) {
166-
irq_entry = &idxd->irq_entries[i];
167-
free_irq(irq_entry->vector, irq_entry);
168-
if (irq_entry->int_handle != INVALID_INT_HANDLE) {
169-
idxd_device_release_int_handle(idxd, irq_entry->int_handle,
170-
IDXD_IRQ_MSIX);
171-
irq_entry->int_handle = INVALID_INT_HANDLE;
172-
irq_entry->pasid = INVALID_IOASID;
148+
ie = &idxd->wqs[i]->ie;
149+
free_irq(ie->vector, ie);
150+
if (ie->int_handle != INVALID_INT_HANDLE) {
151+
idxd_device_release_int_handle(idxd, ie->int_handle, IDXD_IRQ_MSIX);
152+
ie->int_handle = INVALID_INT_HANDLE;
153+
ie->pasid = INVALID_IOASID;
173154
}
174-
irq_entry->vector = -1;
175-
irq_entry->wq = NULL;
176-
irq_entry->idxd = NULL;
155+
ie->vector = -1;
177156
}
178157
err_misc_irq:
179158
/* Disable error interrupt generation */
180159
idxd_mask_error_interrupts(idxd);
181160
idxd_msix_perm_clear(idxd);
182-
err_irq_entries:
183161
pci_free_irq_vectors(pdev);
184162
dev_err(dev, "No usable interrupts\n");
185163
return rc;
@@ -188,21 +166,18 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
188166
static void idxd_cleanup_interrupts(struct idxd_device *idxd)
189167
{
190168
struct pci_dev *pdev = idxd->pdev;
191-
struct idxd_irq_entry *irq_entry;
169+
struct idxd_irq_entry *ie;
192170
int i;
193171

194172
for (i = 0; i < idxd->irq_cnt; i++) {
195-
irq_entry = &idxd->irq_entries[i];
196-
if (irq_entry->int_handle != INVALID_INT_HANDLE) {
197-
idxd_device_release_int_handle(idxd, irq_entry->int_handle,
198-
IDXD_IRQ_MSIX);
199-
irq_entry->int_handle = INVALID_INT_HANDLE;
200-
irq_entry->pasid = INVALID_IOASID;
173+
ie = idxd_get_ie(idxd, i);
174+
if (ie->int_handle != INVALID_INT_HANDLE) {
175+
idxd_device_release_int_handle(idxd, ie->int_handle, IDXD_IRQ_MSIX);
176+
ie->int_handle = INVALID_INT_HANDLE;
177+
ie->pasid = INVALID_IOASID;
201178
}
202-
irq_entry->vector = -1;
203-
irq_entry->wq = NULL;
204-
irq_entry->idxd = NULL;
205-
free_irq(irq_entry->vector, irq_entry);
179+
free_irq(ie->vector, ie);
180+
ie->vector = -1;
206181
}
207182

208183
idxd_mask_error_interrupts(idxd);
@@ -755,7 +730,7 @@ static void idxd_release_int_handles(struct idxd_device *idxd)
755730
int i, rc;
756731

757732
for (i = 1; i < idxd->irq_cnt; i++) {
758-
struct idxd_irq_entry *ie = &idxd->irq_entries[i];
733+
struct idxd_irq_entry *ie = idxd_get_ie(idxd, i);
759734

760735
if (ie->int_handle != INVALID_INT_HANDLE) {
761736
rc = idxd_device_release_int_handle(idxd, ie->int_handle, IDXD_IRQ_MSIX);
@@ -783,7 +758,7 @@ static void idxd_shutdown(struct pci_dev *pdev)
783758
idxd_mask_error_interrupts(idxd);
784759

785760
for (i = 0; i < msixcnt; i++) {
786-
irq_entry = &idxd->irq_entries[i];
761+
irq_entry = idxd_get_ie(idxd, i);
787762
synchronize_irq(irq_entry->vector);
788763
if (i == 0)
789764
continue;
@@ -815,7 +790,7 @@ static void idxd_remove(struct pci_dev *pdev)
815790
idxd_disable_system_pasid(idxd);
816791

817792
for (i = 0; i < msixcnt; i++) {
818-
irq_entry = &idxd->irq_entries[i];
793+
irq_entry = idxd_get_ie(idxd, i);
819794
free_irq(irq_entry->vector, irq_entry);
820795
}
821796
idxd_msix_perm_clear(idxd);

drivers/dma/idxd/irq.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ static void idxd_device_reinit(struct work_struct *work)
7373
*/
7474
static void idxd_int_handle_revoke_drain(struct idxd_irq_entry *ie)
7575
{
76-
struct idxd_wq *wq = ie->wq;
77-
struct idxd_device *idxd = ie->idxd;
76+
struct idxd_wq *wq = ie_to_wq(ie);
77+
struct idxd_device *idxd = wq->idxd;
7878
struct device *dev = &idxd->pdev->dev;
7979
struct dsa_hw_desc desc = {};
8080
void __iomem *portal;
@@ -155,8 +155,8 @@ static void idxd_int_handle_revoke(struct work_struct *work)
155155
* at the end to make sure all invalid int handle descriptors are processed.
156156
*/
157157
for (i = 1; i < idxd->irq_cnt; i++) {
158-
struct idxd_irq_entry *ie = &idxd->irq_entries[i];
159-
struct idxd_wq *wq = ie->wq;
158+
struct idxd_irq_entry *ie = idxd_get_ie(idxd, i);
159+
struct idxd_wq *wq = ie_to_wq(ie);
160160

161161
rc = idxd_device_request_int_handle(idxd, i, &new_handle, IDXD_IRQ_MSIX);
162162
if (rc < 0) {
@@ -338,7 +338,7 @@ static int process_misc_interrupts(struct idxd_device *idxd, u32 cause)
338338
irqreturn_t idxd_misc_thread(int vec, void *data)
339339
{
340340
struct idxd_irq_entry *irq_entry = data;
341-
struct idxd_device *idxd = irq_entry->idxd;
341+
struct idxd_device *idxd = ie_to_idxd(irq_entry);
342342
int rc;
343343
u32 cause;
344344

drivers/dma/idxd/submit.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,8 @@ int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc)
193193
* that we designated the descriptor to.
194194
*/
195195
if (desc_flags & IDXD_OP_FLAG_RCI) {
196-
ie = wq->ie;
197-
if (ie->int_handle == INVALID_INT_HANDLE)
198-
desc->hw->int_handle = ie->id;
199-
else
200-
desc->hw->int_handle = ie->int_handle;
201-
196+
ie = &wq->ie;
197+
desc->hw->int_handle = ie->int_handle;
202198
llist_add(&desc->llnode, &ie->pending_llist);
203199
}
204200

drivers/dma/idxd/sysfs.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1304,7 +1304,6 @@ static void idxd_conf_device_release(struct device *dev)
13041304
kfree(idxd->groups);
13051305
kfree(idxd->wqs);
13061306
kfree(idxd->engines);
1307-
kfree(idxd->irq_entries);
13081307
ida_free(&idxd_ida, idxd->id);
13091308
kfree(idxd);
13101309
}

0 commit comments

Comments
 (0)