Skip to content

Commit 505cc26

Browse files
Shiraz Saleemrleon
authored andcommitted
net: mana: Add support for auxiliary device servicing events
Handle soc servicing events which require the rdma auxiliary device resources to be cleaned up during a suspend, and re-initialized during a resume. Signed-off-by: Shiraz Saleem <shirazsaleem@microsoft.com> Signed-off-by: Konstantin Taranov <kotaranov@microsoft.com> Link: https://patch.msgid.link/1746633545-17653-5-git-send-email-kotaranov@linux.microsoft.com Signed-off-by: Leon Romanovsky <leon@kernel.org>
1 parent d4293f9 commit 505cc26

File tree

5 files changed

+126
-1
lines changed

5 files changed

+126
-1
lines changed

drivers/net/ethernet/microsoft/mana/gdma_main.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@ static void mana_gd_process_eqe(struct gdma_queue *eq)
391391
case GDMA_EQE_HWC_INIT_EQ_ID_DB:
392392
case GDMA_EQE_HWC_INIT_DATA:
393393
case GDMA_EQE_HWC_INIT_DONE:
394+
case GDMA_EQE_HWC_SOC_SERVICE:
394395
case GDMA_EQE_RNIC_QP_FATAL:
395396
if (!eq->eq.callback)
396397
break;
@@ -1468,10 +1469,14 @@ static int mana_gd_setup(struct pci_dev *pdev)
14681469
mana_gd_init_registers(pdev);
14691470
mana_smc_init(&gc->shm_channel, gc->dev, gc->shm_base);
14701471

1472+
gc->service_wq = alloc_ordered_workqueue("gdma_service_wq", 0);
1473+
if (!gc->service_wq)
1474+
return -ENOMEM;
1475+
14711476
err = mana_gd_setup_irqs(pdev);
14721477
if (err) {
14731478
dev_err(gc->dev, "Failed to setup IRQs: %d\n", err);
1474-
return err;
1479+
goto free_workqueue;
14751480
}
14761481

14771482
err = mana_hwc_create_channel(gc);
@@ -1497,6 +1502,8 @@ static int mana_gd_setup(struct pci_dev *pdev)
14971502
mana_hwc_destroy_channel(gc);
14981503
remove_irq:
14991504
mana_gd_remove_irqs(pdev);
1505+
free_workqueue:
1506+
destroy_workqueue(gc->service_wq);
15001507
dev_err(&pdev->dev, "%s failed (error %d)\n", __func__, err);
15011508
return err;
15021509
}
@@ -1508,6 +1515,8 @@ static void mana_gd_cleanup(struct pci_dev *pdev)
15081515
mana_hwc_destroy_channel(gc);
15091516

15101517
mana_gd_remove_irqs(pdev);
1518+
1519+
destroy_workqueue(gc->service_wq);
15111520
dev_dbg(&pdev->dev, "mana gdma cleanup successful\n");
15121521
}
15131522

drivers/net/ethernet/microsoft/mana/hw_channel.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,13 @@ static void mana_hwc_handle_resp(struct hw_channel_context *hwc, u32 resp_len,
112112
static void mana_hwc_init_event_handler(void *ctx, struct gdma_queue *q_self,
113113
struct gdma_event *event)
114114
{
115+
union hwc_init_soc_service_type service_data;
115116
struct hw_channel_context *hwc = ctx;
116117
struct gdma_dev *gd = hwc->gdma_dev;
117118
union hwc_init_type_data type_data;
118119
union hwc_init_eq_id_db eq_db;
119120
u32 type, val;
121+
int ret;
120122

121123
switch (event->type) {
122124
case GDMA_EQE_HWC_INIT_EQ_ID_DB:
@@ -199,7 +201,24 @@ static void mana_hwc_init_event_handler(void *ctx, struct gdma_queue *q_self,
199201
}
200202

201203
break;
204+
case GDMA_EQE_HWC_SOC_SERVICE:
205+
service_data.as_uint32 = event->details[0];
206+
type = service_data.type;
202207

208+
switch (type) {
209+
case GDMA_SERVICE_TYPE_RDMA_SUSPEND:
210+
case GDMA_SERVICE_TYPE_RDMA_RESUME:
211+
ret = mana_rdma_service_event(gd->gdma_context, type);
212+
if (ret)
213+
dev_err(hwc->dev, "Failed to schedule adev service event: %d\n",
214+
ret);
215+
break;
216+
default:
217+
dev_warn(hwc->dev, "Received unknown SOC service type %u\n", type);
218+
break;
219+
}
220+
221+
break;
203222
default:
204223
dev_warn(hwc->dev, "Received unknown gdma event %u\n", event->type);
205224
/* Ignore unknown events, which should never happen. */

drivers/net/ethernet/microsoft/mana/mana_en.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2993,6 +2993,70 @@ static int add_adev(struct gdma_dev *gd, const char *name)
29932993
return ret;
29942994
}
29952995

2996+
static void mana_rdma_service_handle(struct work_struct *work)
2997+
{
2998+
struct mana_service_work *serv_work =
2999+
container_of(work, struct mana_service_work, work);
3000+
struct gdma_dev *gd = serv_work->gdma_dev;
3001+
struct device *dev = gd->gdma_context->dev;
3002+
int ret;
3003+
3004+
if (READ_ONCE(gd->rdma_teardown))
3005+
goto out;
3006+
3007+
switch (serv_work->event) {
3008+
case GDMA_SERVICE_TYPE_RDMA_SUSPEND:
3009+
if (!gd->adev || gd->is_suspended)
3010+
break;
3011+
3012+
remove_adev(gd);
3013+
gd->is_suspended = true;
3014+
break;
3015+
3016+
case GDMA_SERVICE_TYPE_RDMA_RESUME:
3017+
if (!gd->is_suspended)
3018+
break;
3019+
3020+
ret = add_adev(gd, "rdma");
3021+
if (ret)
3022+
dev_err(dev, "Failed to add adev on resume: %d\n", ret);
3023+
else
3024+
gd->is_suspended = false;
3025+
break;
3026+
3027+
default:
3028+
dev_warn(dev, "unknown adev service event %u\n",
3029+
serv_work->event);
3030+
break;
3031+
}
3032+
3033+
out:
3034+
kfree(serv_work);
3035+
}
3036+
3037+
int mana_rdma_service_event(struct gdma_context *gc, enum gdma_service_type event)
3038+
{
3039+
struct gdma_dev *gd = &gc->mana_ib;
3040+
struct mana_service_work *serv_work;
3041+
3042+
if (gd->dev_id.type != GDMA_DEVICE_MANA_IB) {
3043+
/* RDMA device is not detected on pci */
3044+
return 0;
3045+
}
3046+
3047+
serv_work = kzalloc(sizeof(*serv_work), GFP_ATOMIC);
3048+
if (!serv_work)
3049+
return -ENOMEM;
3050+
3051+
serv_work->event = event;
3052+
serv_work->gdma_dev = gd;
3053+
3054+
INIT_WORK(&serv_work->work, mana_rdma_service_handle);
3055+
queue_work(gc->service_wq, &serv_work->work);
3056+
3057+
return 0;
3058+
}
3059+
29963060
int mana_probe(struct gdma_dev *gd, bool resuming)
29973061
{
29983062
struct gdma_context *gc = gd->gdma_context;
@@ -3173,11 +3237,16 @@ int mana_rdma_probe(struct gdma_dev *gd)
31733237

31743238
void mana_rdma_remove(struct gdma_dev *gd)
31753239
{
3240+
struct gdma_context *gc = gd->gdma_context;
3241+
31763242
if (gd->dev_id.type != GDMA_DEVICE_MANA_IB) {
31773243
/* RDMA device is not detected on pci */
31783244
return;
31793245
}
31803246

3247+
WRITE_ONCE(gd->rdma_teardown, true);
3248+
flush_workqueue(gc->service_wq);
3249+
31813250
if (gd->adev)
31823251
remove_adev(gd);
31833252

include/net/mana/gdma.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ enum gdma_eqe_type {
6060
GDMA_EQE_HWC_INIT_DONE = 131,
6161
GDMA_EQE_HWC_SOC_RECONFIG = 132,
6262
GDMA_EQE_HWC_SOC_RECONFIG_DATA = 133,
63+
GDMA_EQE_HWC_SOC_SERVICE = 134,
6364
GDMA_EQE_RNIC_QP_FATAL = 176,
6465
};
6566

@@ -70,6 +71,18 @@ enum {
7071
GDMA_DEVICE_MANA_IB = 3,
7172
};
7273

74+
enum gdma_service_type {
75+
GDMA_SERVICE_TYPE_NONE = 0,
76+
GDMA_SERVICE_TYPE_RDMA_SUSPEND = 1,
77+
GDMA_SERVICE_TYPE_RDMA_RESUME = 2,
78+
};
79+
80+
struct mana_service_work {
81+
struct work_struct work;
82+
struct gdma_dev *gdma_dev;
83+
enum gdma_service_type event;
84+
};
85+
7386
struct gdma_resource {
7487
/* Protect the bitmap */
7588
spinlock_t lock;
@@ -224,6 +237,8 @@ struct gdma_dev {
224237
void *driver_data;
225238

226239
struct auxiliary_device *adev;
240+
bool is_suspended;
241+
bool rdma_teardown;
227242
};
228243

229244
/* MANA_PAGE_SIZE is the DMA unit */
@@ -409,6 +424,8 @@ struct gdma_context {
409424
struct gdma_dev mana_ib;
410425

411426
u64 pf_cap_flags1;
427+
428+
struct workqueue_struct *service_wq;
412429
};
413430

414431
static inline bool mana_gd_is_mana(struct gdma_dev *gd)
@@ -891,4 +908,6 @@ int mana_gd_destroy_dma_region(struct gdma_context *gc, u64 dma_region_handle);
891908
void mana_register_debugfs(void);
892909
void mana_unregister_debugfs(void);
893910

911+
int mana_rdma_service_event(struct gdma_context *gc, enum gdma_service_type event);
912+
894913
#endif /* _GDMA_H */

include/net/mana/hw_channel.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ union hwc_init_type_data {
4949
};
5050
}; /* HW DATA */
5151

52+
union hwc_init_soc_service_type {
53+
u32 as_uint32;
54+
55+
struct {
56+
u32 value : 28;
57+
u32 type : 4;
58+
};
59+
}; /* HW DATA */
60+
5261
struct hwc_rx_oob {
5362
u32 type : 6;
5463
u32 eom : 1;

0 commit comments

Comments
 (0)