Skip to content

Commit 80fa93f

Browse files
mikeympe
authored andcommitted
cxl: Name interrupts in /proc/interrupt
Currently all interrupts generated by cxl are named "cxl". This is not very informative as we can't distinguish between cards, AFUs, error interrupts, user contexts and user interrupts numbers. Being able to distinguish them is useful for setting affinity. This patch gives each of these names in /proc/interrupts. A two card CAPI system, with afu0.0 having 2 active contexts each with 4 user IRQs each, will now look like this: % grep cxl /proc/interrupts 444: 0 OPAL ICS 141312 Level cxl-card1-err 445: 0 OPAL ICS 141313 Level cxl-afu1.0-err 446: 0 OPAL ICS 141314 Level cxl-afu1.0 462: 0 OPAL ICS 2052 Level cxl-afu0.0-pe0-1 463: 75517 OPAL ICS 2053 Level cxl-afu0.0-pe0-2 468: 0 OPAL ICS 2054 Level cxl-afu0.0-pe0-3 469: 0 OPAL ICS 2055 Level cxl-afu0.0-pe0-4 470: 0 OPAL ICS 2056 Level cxl-afu0.0-pe1-1 471: 75506 OPAL ICS 2057 Level cxl-afu0.0-pe1-2 472: 0 OPAL ICS 2058 Level cxl-afu0.0-pe1-3 473: 0 OPAL ICS 2059 Level cxl-afu0.0-pe1-4 502: 1066 OPAL ICS 2050 Level cxl-afu0.0 514: 0 OPAL ICS 2048 Level cxl-card0-err 515: 0 OPAL ICS 2049 Level cxl-afu0.0-err Signed-off-by: Michael Neuling <[email protected]> Signed-off-by: Ian Munsie <[email protected]> Signed-off-by: Michael Ellerman <[email protected]>
1 parent bc78b05 commit 80fa93f

File tree

2 files changed

+98
-13
lines changed

2 files changed

+98
-13
lines changed

drivers/misc/cxl/cxl.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,8 @@ struct cxl_sste {
336336
struct cxl_afu {
337337
irq_hw_number_t psl_hwirq;
338338
irq_hw_number_t serr_hwirq;
339+
char *err_irq_name;
340+
char *psl_irq_name;
339341
unsigned int serr_virq;
340342
void __iomem *p1n_mmio;
341343
void __iomem *p2n_mmio;
@@ -379,6 +381,12 @@ struct cxl_afu {
379381
bool enabled;
380382
};
381383

384+
385+
struct cxl_irq_name {
386+
struct list_head list;
387+
char *name;
388+
};
389+
382390
/*
383391
* This is a cxl context. If the PSL is in dedicated mode, there will be one
384392
* of these per AFU. If in AFU directed there can be lots of these.
@@ -403,6 +411,7 @@ struct cxl_context {
403411

404412
unsigned long *irq_bitmap; /* Accessed from IRQ context */
405413
struct cxl_irq_ranges irqs;
414+
struct list_head irq_names;
406415
u64 fault_addr;
407416
u64 fault_dsisr;
408417
u64 afu_err;
@@ -444,6 +453,7 @@ struct cxl {
444453
struct dentry *trace;
445454
struct dentry *psl_err_chk;
446455
struct dentry *debugfs;
456+
char *irq_name;
447457
struct bin_attribute cxl_attr;
448458
int adapter_num;
449459
int user_irqs;
@@ -563,9 +573,6 @@ int _cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode);
563573
int cxl_afu_deactivate_mode(struct cxl_afu *afu);
564574
int cxl_afu_select_best_mode(struct cxl_afu *afu);
565575

566-
unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq,
567-
irq_handler_t handler, void *cookie);
568-
void cxl_unmap_irq(unsigned int virq, void *cookie);
569576
int cxl_register_psl_irq(struct cxl_afu *afu);
570577
void cxl_release_psl_irq(struct cxl_afu *afu);
571578
int cxl_register_psl_err_irq(struct cxl *adapter);

drivers/misc/cxl/irq.c

Lines changed: 88 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ static irqreturn_t cxl_irq_afu(int irq, void *data)
255255
}
256256

257257
unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq,
258-
irq_handler_t handler, void *cookie)
258+
irq_handler_t handler, void *cookie, const char *name)
259259
{
260260
unsigned int virq;
261261
int result;
@@ -271,7 +271,7 @@ unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq,
271271

272272
pr_devel("hwirq %#lx mapped to virq %u\n", hwirq, virq);
273273

274-
result = request_irq(virq, handler, 0, "cxl", cookie);
274+
result = request_irq(virq, handler, 0, name, cookie);
275275
if (result) {
276276
dev_warn(&adapter->dev, "cxl_map_irq: request_irq failed: %i\n", result);
277277
return 0;
@@ -290,14 +290,15 @@ static int cxl_register_one_irq(struct cxl *adapter,
290290
irq_handler_t handler,
291291
void *cookie,
292292
irq_hw_number_t *dest_hwirq,
293-
unsigned int *dest_virq)
293+
unsigned int *dest_virq,
294+
const char *name)
294295
{
295296
int hwirq, virq;
296297

297298
if ((hwirq = cxl_alloc_one_irq(adapter)) < 0)
298299
return hwirq;
299300

300-
if (!(virq = cxl_map_irq(adapter, hwirq, handler, cookie)))
301+
if (!(virq = cxl_map_irq(adapter, hwirq, handler, cookie, name)))
301302
goto err;
302303

303304
*dest_hwirq = hwirq;
@@ -314,10 +315,19 @@ int cxl_register_psl_err_irq(struct cxl *adapter)
314315
{
315316
int rc;
316317

318+
adapter->irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err",
319+
dev_name(&adapter->dev));
320+
if (!adapter->irq_name)
321+
return -ENOMEM;
322+
317323
if ((rc = cxl_register_one_irq(adapter, cxl_irq_err, adapter,
318324
&adapter->err_hwirq,
319-
&adapter->err_virq)))
325+
&adapter->err_virq,
326+
adapter->irq_name))) {
327+
kfree(adapter->irq_name);
328+
adapter->irq_name = NULL;
320329
return rc;
330+
}
321331

322332
cxl_p1_write(adapter, CXL_PSL_ErrIVTE, adapter->err_hwirq & 0xffff);
323333

@@ -329,17 +339,26 @@ void cxl_release_psl_err_irq(struct cxl *adapter)
329339
cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000);
330340
cxl_unmap_irq(adapter->err_virq, adapter);
331341
cxl_release_one_irq(adapter, adapter->err_hwirq);
342+
kfree(adapter->irq_name);
332343
}
333344

334345
int cxl_register_serr_irq(struct cxl_afu *afu)
335346
{
336347
u64 serr;
337348
int rc;
338349

350+
afu->err_irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err",
351+
dev_name(&afu->dev));
352+
if (!afu->err_irq_name)
353+
return -ENOMEM;
354+
339355
if ((rc = cxl_register_one_irq(afu->adapter, cxl_slice_irq_err, afu,
340356
&afu->serr_hwirq,
341-
&afu->serr_virq)))
357+
&afu->serr_virq, afu->err_irq_name))) {
358+
kfree(afu->err_irq_name);
359+
afu->err_irq_name = NULL;
342360
return rc;
361+
}
343362

344363
serr = cxl_p1n_read(afu, CXL_PSL_SERR_An);
345364
serr = (serr & 0x00ffffffffff0000ULL) | (afu->serr_hwirq & 0xffff);
@@ -353,24 +372,50 @@ void cxl_release_serr_irq(struct cxl_afu *afu)
353372
cxl_p1n_write(afu, CXL_PSL_SERR_An, 0x0000000000000000);
354373
cxl_unmap_irq(afu->serr_virq, afu);
355374
cxl_release_one_irq(afu->adapter, afu->serr_hwirq);
375+
kfree(afu->err_irq_name);
356376
}
357377

358378
int cxl_register_psl_irq(struct cxl_afu *afu)
359379
{
360-
return cxl_register_one_irq(afu->adapter, cxl_irq_multiplexed, afu,
361-
&afu->psl_hwirq, &afu->psl_virq);
380+
int rc;
381+
382+
afu->psl_irq_name = kasprintf(GFP_KERNEL, "cxl-%s",
383+
dev_name(&afu->dev));
384+
if (!afu->psl_irq_name)
385+
return -ENOMEM;
386+
387+
if ((rc = cxl_register_one_irq(afu->adapter, cxl_irq_multiplexed, afu,
388+
&afu->psl_hwirq, &afu->psl_virq,
389+
afu->psl_irq_name))) {
390+
kfree(afu->psl_irq_name);
391+
afu->psl_irq_name = NULL;
392+
}
393+
return rc;
362394
}
363395

364396
void cxl_release_psl_irq(struct cxl_afu *afu)
365397
{
366398
cxl_unmap_irq(afu->psl_virq, afu);
367399
cxl_release_one_irq(afu->adapter, afu->psl_hwirq);
400+
kfree(afu->psl_irq_name);
401+
}
402+
403+
void afu_irq_name_free(struct cxl_context *ctx)
404+
{
405+
struct cxl_irq_name *irq_name, *tmp;
406+
407+
list_for_each_entry_safe(irq_name, tmp, &ctx->irq_names, list) {
408+
kfree(irq_name->name);
409+
list_del(&irq_name->list);
410+
kfree(irq_name);
411+
}
368412
}
369413

370414
int afu_register_irqs(struct cxl_context *ctx, u32 count)
371415
{
372416
irq_hw_number_t hwirq;
373-
int rc, r, i;
417+
int rc, r, i, j = 1;
418+
struct cxl_irq_name *irq_name;
374419

375420
if ((rc = cxl_alloc_irq_ranges(&ctx->irqs, ctx->afu->adapter, count)))
376421
return rc;
@@ -384,15 +429,47 @@ int afu_register_irqs(struct cxl_context *ctx, u32 count)
384429
sizeof(*ctx->irq_bitmap), GFP_KERNEL);
385430
if (!ctx->irq_bitmap)
386431
return -ENOMEM;
432+
433+
/*
434+
* Allocate names first. If any fail, bail out before allocating
435+
* actual hardware IRQs.
436+
*/
437+
INIT_LIST_HEAD(&ctx->irq_names);
438+
for (r = 1; r < CXL_IRQ_RANGES; r++) {
439+
for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) {
440+
irq_name = kmalloc(sizeof(struct cxl_irq_name),
441+
GFP_KERNEL);
442+
if (!irq_name)
443+
goto out;
444+
irq_name->name = kasprintf(GFP_KERNEL, "cxl-%s-pe%i-%i",
445+
dev_name(&ctx->afu->dev),
446+
ctx->pe, j);
447+
if (!irq_name->name) {
448+
kfree(irq_name);
449+
goto out;
450+
}
451+
/* Add to tail so next look get the correct order */
452+
list_add_tail(&irq_name->list, &ctx->irq_names);
453+
j++;
454+
}
455+
}
456+
457+
/* We've allocated all memory now, so let's do the irq allocations */
458+
irq_name = list_first_entry(&ctx->irq_names, struct cxl_irq_name, list);
387459
for (r = 1; r < CXL_IRQ_RANGES; r++) {
388460
hwirq = ctx->irqs.offset[r];
389461
for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) {
390462
cxl_map_irq(ctx->afu->adapter, hwirq,
391-
cxl_irq_afu, ctx);
463+
cxl_irq_afu, ctx, irq_name->name);
464+
irq_name = list_next_entry(irq_name, list);
392465
}
393466
}
394467

395468
return 0;
469+
470+
out:
471+
afu_irq_name_free(ctx);
472+
return -ENOMEM;
396473
}
397474

398475
void afu_release_irqs(struct cxl_context *ctx)
@@ -410,5 +487,6 @@ void afu_release_irqs(struct cxl_context *ctx)
410487
}
411488
}
412489

490+
afu_irq_name_free(ctx);
413491
cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
414492
}

0 commit comments

Comments
 (0)