Skip to content

Commit ca1d766

Browse files
Salil Mehtadavem330
authored andcommitted
net: hns3: Refactor of the reset interrupt handling logic
The reset interrupt event shares common miscellaneous interrupt Vector 0. In the existing reset interrupt handling we disable the Vector 0 interrupt in misc interrupt handler and re-enable them later in context to common service task. This also means other event sources like mailbox would also be deferred or if the interrupt event was due to mailbox(which shall be supported for VF soon), it could delay the reset handling. This patch reorganizes the reset interrupt handling logic and makes it more fair to other events. Signed-off-by: Salil Mehta <salil.mehta@huawei.com> Signed-off-by: lipeng <lipeng321@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 81da3bf commit ca1d766

File tree

2 files changed

+78
-32
lines changed

2 files changed

+78
-32
lines changed

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c

Lines changed: 71 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2362,6 +2362,46 @@ static void hclge_service_complete(struct hclge_dev *hdev)
23622362
clear_bit(HCLGE_STATE_SERVICE_SCHED, &hdev->state);
23632363
}
23642364

2365+
static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
2366+
{
2367+
u32 rst_src_reg;
2368+
2369+
/* fetch the events from their corresponding regs */
2370+
rst_src_reg = hclge_read_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG);
2371+
2372+
/* check for vector0 reset event sources */
2373+
if (BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B) & rst_src_reg) {
2374+
set_bit(HNAE3_GLOBAL_RESET, &hdev->reset_pending);
2375+
*clearval = BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B);
2376+
return HCLGE_VECTOR0_EVENT_RST;
2377+
}
2378+
2379+
if (BIT(HCLGE_VECTOR0_CORERESET_INT_B) & rst_src_reg) {
2380+
set_bit(HNAE3_CORE_RESET, &hdev->reset_pending);
2381+
*clearval = BIT(HCLGE_VECTOR0_CORERESET_INT_B);
2382+
return HCLGE_VECTOR0_EVENT_RST;
2383+
}
2384+
2385+
if (BIT(HCLGE_VECTOR0_IMPRESET_INT_B) & rst_src_reg) {
2386+
set_bit(HNAE3_IMP_RESET, &hdev->reset_pending);
2387+
*clearval = BIT(HCLGE_VECTOR0_IMPRESET_INT_B);
2388+
return HCLGE_VECTOR0_EVENT_RST;
2389+
}
2390+
2391+
/* mailbox event sharing vector 0 interrupt would be placed here */
2392+
2393+
return HCLGE_VECTOR0_EVENT_OTHER;
2394+
}
2395+
2396+
static void hclge_clear_event_cause(struct hclge_dev *hdev, u32 event_type,
2397+
u32 regclr)
2398+
{
2399+
if (event_type == HCLGE_VECTOR0_EVENT_RST)
2400+
hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, regclr);
2401+
2402+
/* mailbox event sharing vector 0 interrupt would be placed here */
2403+
}
2404+
23652405
static void hclge_enable_vector(struct hclge_misc_vector *vector, bool enable)
23662406
{
23672407
writel(enable ? 1 : 0, vector->addr);
@@ -2370,10 +2410,28 @@ static void hclge_enable_vector(struct hclge_misc_vector *vector, bool enable)
23702410
static irqreturn_t hclge_misc_irq_handle(int irq, void *data)
23712411
{
23722412
struct hclge_dev *hdev = data;
2413+
u32 event_cause;
2414+
u32 clearval;
23732415

23742416
hclge_enable_vector(&hdev->misc_vector, false);
2375-
if (!test_and_set_bit(HCLGE_STATE_SERVICE_SCHED, &hdev->state))
2376-
schedule_work(&hdev->service_task);
2417+
event_cause = hclge_check_event_cause(hdev, &clearval);
2418+
2419+
/* vector 0 interrupt is shared with reset and mailbox source events.
2420+
* For now, we are not handling mailbox events.
2421+
*/
2422+
switch (event_cause) {
2423+
case HCLGE_VECTOR0_EVENT_RST:
2424+
/* reset task to be scheduled here */
2425+
break;
2426+
default:
2427+
dev_dbg(&hdev->pdev->dev,
2428+
"received unknown or unhandled event of vector0\n");
2429+
break;
2430+
}
2431+
2432+
/* we should clear the source of interrupt */
2433+
hclge_clear_event_cause(hdev, event_cause, clearval);
2434+
hclge_enable_vector(&hdev->misc_vector, true);
23772435

23782436
return IRQ_HANDLED;
23792437
}
@@ -2404,9 +2462,9 @@ static int hclge_misc_irq_init(struct hclge_dev *hdev)
24042462

24052463
hclge_get_misc_vector(hdev);
24062464

2407-
ret = devm_request_irq(&hdev->pdev->dev,
2408-
hdev->misc_vector.vector_irq,
2409-
hclge_misc_irq_handle, 0, "hclge_misc", hdev);
2465+
/* this would be explicitly freed in the end */
2466+
ret = request_irq(hdev->misc_vector.vector_irq, hclge_misc_irq_handle,
2467+
0, "hclge_misc", hdev);
24102468
if (ret) {
24112469
hclge_free_vector(hdev, 0);
24122470
dev_err(&hdev->pdev->dev, "request misc irq(%d) fail\n",
@@ -2416,6 +2474,12 @@ static int hclge_misc_irq_init(struct hclge_dev *hdev)
24162474
return ret;
24172475
}
24182476

2477+
static void hclge_misc_irq_uninit(struct hclge_dev *hdev)
2478+
{
2479+
free_irq(hdev->misc_vector.vector_irq, hdev);
2480+
hclge_free_vector(hdev, 0);
2481+
}
2482+
24192483
static int hclge_notify_client(struct hclge_dev *hdev,
24202484
enum hnae3_reset_notify_type type)
24212485
{
@@ -2471,12 +2535,6 @@ static int hclge_reset_wait(struct hclge_dev *hdev)
24712535
cnt++;
24722536
}
24732537

2474-
/* must clear reset status register to
2475-
* prevent driver detect reset interrupt again
2476-
*/
2477-
reg = hclge_read_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG);
2478-
hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, reg);
2479-
24802538
if (cnt >= HCLGE_RESET_WAIT_CNT) {
24812539
dev_warn(&hdev->pdev->dev,
24822540
"Wait for reset timeout: %d\n", hdev->reset_type);
@@ -2534,22 +2592,6 @@ static void hclge_do_reset(struct hclge_dev *hdev, enum hnae3_reset_type type)
25342592
}
25352593
}
25362594

2537-
static enum hnae3_reset_type hclge_detected_reset_event(struct hclge_dev *hdev)
2538-
{
2539-
enum hnae3_reset_type rst_level = HNAE3_NONE_RESET;
2540-
u32 rst_reg_val;
2541-
2542-
rst_reg_val = hclge_read_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG);
2543-
if (BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B) & rst_reg_val)
2544-
rst_level = HNAE3_GLOBAL_RESET;
2545-
else if (BIT(HCLGE_VECTOR0_CORERESET_INT_B) & rst_reg_val)
2546-
rst_level = HNAE3_CORE_RESET;
2547-
else if (BIT(HCLGE_VECTOR0_IMPRESET_INT_B) & rst_reg_val)
2548-
rst_level = HNAE3_IMP_RESET;
2549-
2550-
return rst_level;
2551-
}
2552-
25532595
static void hclge_reset_event(struct hnae3_handle *handle,
25542596
enum hnae3_reset_type reset)
25552597
{
@@ -2584,9 +2626,6 @@ static void hclge_reset_subtask(struct hclge_dev *hdev)
25842626

25852627
do_reset = hdev->reset_type != HNAE3_NONE_RESET;
25862628

2587-
/* Reset is detected by interrupt */
2588-
if (hdev->reset_type == HNAE3_NONE_RESET)
2589-
hdev->reset_type = hclge_detected_reset_event(hdev);
25902629

25912630
if (hdev->reset_type == HNAE3_NONE_RESET)
25922631
return;
@@ -2622,7 +2661,6 @@ static void hclge_reset_subtask(struct hclge_dev *hdev)
26222661
static void hclge_misc_irq_service_task(struct hclge_dev *hdev)
26232662
{
26242663
hclge_reset_subtask(hdev);
2625-
hclge_enable_vector(&hdev->misc_vector, true);
26262664
}
26272665

26282666
static void hclge_service_task(struct work_struct *work)
@@ -4661,6 +4699,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
46614699
hdev->pdev = pdev;
46624700
hdev->ae_dev = ae_dev;
46634701
hdev->reset_type = HNAE3_NONE_RESET;
4702+
hdev->reset_pending = 0;
46644703
ae_dev->priv = hdev;
46654704

46664705
ret = hclge_pci_init(hdev);
@@ -4895,8 +4934,8 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev)
48954934

48964935
/* Disable MISC vector(vector0) */
48974936
hclge_enable_vector(&hdev->misc_vector, false);
4898-
hclge_free_vector(hdev, 0);
48994937
hclge_destroy_cmd_queue(&hdev->hw);
4938+
hclge_misc_irq_uninit(hdev);
49004939
hclge_pci_uninit(hdev);
49014940
ae_dev->priv = NULL;
49024941
}

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,12 @@ enum HCLGE_DEV_STATE {
105105
HCLGE_STATE_MAX
106106
};
107107

108+
enum hclge_evt_cause {
109+
HCLGE_VECTOR0_EVENT_RST,
110+
HCLGE_VECTOR0_EVENT_MBX,
111+
HCLGE_VECTOR0_EVENT_OTHER,
112+
};
113+
108114
#define HCLGE_MPF_ENBALE 1
109115
struct hclge_caps {
110116
u16 num_tqp;
@@ -420,6 +426,7 @@ struct hclge_dev {
420426
unsigned long state;
421427

422428
enum hnae3_reset_type reset_type;
429+
unsigned long reset_pending; /* client rst is pending to be served */
423430
u32 fw_version;
424431
u16 num_vmdq_vport; /* Num vmdq vport this PF has set up */
425432
u16 num_tqps; /* Num task queue pairs of this PF */

0 commit comments

Comments
 (0)