
From: Junxian Huang <huangjunxian6@hisilicon.com> driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I6Z4E9 --------------------------------------------------------------- Currently, bond_work, the struct of delayed work for RoCE bonding, is attached to hns_roce_dev. During setting bond, hns_roce_dev will be uninited and the pending works will be canceled. This patch moves bond_work from hns_roce_dev to hns_roce_bond_group so that the pending works can be executed after setting bond rather than being cancelled. Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com> --- drivers/infiniband/hw/hns/hns_roce_bond.c | 27 ++++++++++++--------- drivers/infiniband/hw/hns/hns_roce_bond.h | 1 + drivers/infiniband/hw/hns/hns_roce_device.h | 1 - 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_bond.c b/drivers/infiniband/hw/hns/hns_roce_bond.c index c1e35792246e..17c1a84f8496 100644 --- a/drivers/infiniband/hw/hns/hns_roce_bond.c +++ b/drivers/infiniband/hw/hns/hns_roce_bond.c @@ -107,10 +107,10 @@ struct net_device *hns_roce_get_bond_netdev(struct hns_roce_dev *hr_dev) return net_dev; } -static void hns_roce_queue_bond_work(struct hns_roce_dev *hr_dev, +static void hns_roce_queue_bond_work(struct hns_roce_bond_group *bond_grp, unsigned long delay) { - schedule_delayed_work(&hr_dev->bond_work, delay); + schedule_delayed_work(&bond_grp->bond_work, delay); } static void hns_roce_bond_get_active_slave(struct hns_roce_bond_group *bond_grp) @@ -378,20 +378,21 @@ static void hns_roce_do_bond(struct hns_roce_bond_group *bond_grp) void hns_roce_do_bond_work(struct work_struct *work) { + struct hns_roce_bond_group *bond_grp; struct delayed_work *delayed_work; - struct hns_roce_dev *hr_dev; int status; delayed_work = to_delayed_work(work); - hr_dev = container_of(delayed_work, struct hns_roce_dev, bond_work); + bond_grp = container_of(delayed_work, struct hns_roce_bond_group, + bond_work); status = mutex_trylock(&roce_bond_mutex); if (!status) { /* delay 1 sec */ - hns_roce_queue_bond_work(hr_dev, HZ); + hns_roce_queue_bond_work(bond_grp, HZ); return; } - hns_roce_do_bond(hr_dev->bond_grp); + hns_roce_do_bond(bond_grp); mutex_unlock(&roce_bond_mutex); } @@ -399,8 +400,6 @@ int hns_roce_bond_init(struct hns_roce_dev *hr_dev) { int ret; - INIT_DELAYED_WORK(&hr_dev->bond_work, hns_roce_do_bond_work); - hr_dev->bond_nb.notifier_call = hns_roce_bond_event; ret = register_netdevice_notifier(&hr_dev->bond_nb); if (ret) { @@ -415,10 +414,11 @@ int hns_roce_bond_init(struct hns_roce_dev *hr_dev) void hns_roce_cleanup_bond(struct hns_roce_dev *hr_dev) { unregister_netdevice_notifier(&hr_dev->bond_nb); - cancel_delayed_work(&hr_dev->bond_work); - if (hr_dev->bond_grp && hr_dev == hr_dev->bond_grp->main_hr_dev) + if (hr_dev->bond_grp && hr_dev == hr_dev->bond_grp->main_hr_dev) { + cancel_delayed_work(&hr_dev->bond_grp->bond_work); kfree(hr_dev->bond_grp); + } hr_dev->bond_grp = NULL; } @@ -561,6 +561,9 @@ static struct hns_roce_bond_group *hns_roce_alloc_bond_grp(struct hns_roce_dev * return NULL; mutex_init(&bond_grp->bond_mutex); + + INIT_DELAYED_WORK(&bond_grp->bond_work, hns_roce_do_bond_work); + bond_grp->upper_dev = upper_dev; bond_grp->main_hr_dev = main_hr_dev; bond_grp->main_net_dev = main_hr_dev->iboe.netdevs[0]; @@ -698,7 +701,7 @@ int hns_roce_bond_event(struct notifier_block *self, } if (support == BOND_EXISTING_NOT_SUPPORT) { hr_dev->bond_grp->bond_ready = false; - hns_roce_queue_bond_work(hr_dev, HZ); + hns_roce_queue_bond_work(hr_dev->bond_grp, HZ); return NOTIFY_DONE; } changed = hns_roce_bond_upper_event(hr_dev, ptr); @@ -706,7 +709,7 @@ int hns_roce_bond_event(struct notifier_block *self, changed = hns_roce_bond_lowerstate_event(hr_dev, ptr); } if (changed) - hns_roce_queue_bond_work(hr_dev, HZ); + hns_roce_queue_bond_work(hr_dev->bond_grp, HZ); return NOTIFY_DONE; } diff --git a/drivers/infiniband/hw/hns/hns_roce_bond.h b/drivers/infiniband/hw/hns/hns_roce_bond.h index 6fccf4762e86..65a19d781847 100644 --- a/drivers/infiniband/hw/hns/hns_roce_bond.h +++ b/drivers/infiniband/hw/hns/hns_roce_bond.h @@ -67,6 +67,7 @@ struct hns_roce_bond_group { */ struct mutex bond_mutex; struct hns_roce_func_info bond_func_info[ROCE_BOND_FUNC_MAX]; + struct delayed_work bond_work; }; int hns_roce_bond_init(struct hns_roce_dev *hr_dev); diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 68a9bed853a1..7fbfdbed0f4d 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -1124,7 +1124,6 @@ struct hns_roce_dev { u64 dwqe_page; struct notifier_block bond_nb; - struct delayed_work bond_work; struct hns_roce_bond_group *bond_grp; struct netdev_lag_lower_state_info slave_state; struct hns_roce_port port_data[HNS_ROCE_MAX_PORTS]; -- 2.30.0