On 2019/11/8 2:28, Jason Gunthorpe wrote: > On Thu, Nov 07, 2019 at 08:48:25PM +0800, Liuyixian (Eason) wrote: >> >> >> On 2019/11/7 4:40, Jason Gunthorpe wrote: >>> On Mon, Oct 28, 2019 at 05:45:44PM +0800, Yixian Liu wrote: >>>> @@ -1998,6 +2000,17 @@ static int hns_roce_v2_init(struct hns_roce_dev *hr_dev) >>>> } >>>> } >>>> >>>> + snprintf(workq_name, HNS_ROCE_WORKQ_NAME_LEN - 1, >>>> + "hns_roce_%d_flush_wq", device_id); >>>> + device_id++; >>>> + >>>> + hr_dev->flush_workq = alloc_workqueue(workq_name, WQ_HIGHPRI, 0); >>>> + if (!hr_dev->flush_workq) { >>> >>> Why is this so time critical? >> >> Hi Jason, >> >> I am not quite sure whether you concerned with the flag "WQ_HIGHPRI" or >> why WQ is created in hns_roce_v2_init. > > Yes, why do you need a dedicated HIGHPRI work queue. As hip08 hardware needs driver to help to do flush operation, I am not sure the application can perceive that qp state is error without receiving flush cqe if work in WQ is not scheduled in time. > >> If it is WQ_HIGHPRI, yes, it is much better to implement flush operation >> ASAP to help generating flushed cqe as ULP may poll cqe urgently. If you >> concerned allocation stage, as flush operation is support for hip08 only, >> there is no other place proper than here I think. > > Why? This is only something that happens in error cases. Yes, maybe we can move out WQ_HIGHPRI flag safely, will fix it in v2. > >>> Why don't you do this from hns_roce_irq_work_handle() ? >> >> As described in the cover letter, here we used CMWQ (concurrency management workqueue) >> to make sure that flush operation can be implemented ASAP. Current irq workqueue is >> a singlethread workqueue, which may delay the flush too long when the system is heavy. >> >> Do you mean we can change irq workqueue to CMWQ to put flush work into it? > > As far as I could tell the only thing the triggered the work to run > was some variable which was only set in another work queue 'hns_roce_irq_work_handle()' OK, thanks. I will consider you suggestion and reuse the irq workqueue. > >>>> +} >>>> + >>>> +void init_flush_work(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp) >>>> +{ >>>> + struct hns_roce_flush_work *flush_work; >>>> + >>>> + flush_work = kzalloc(sizeof(struct hns_roce_flush_work), GFP_ATOMIC); >>>> + if (!flush_work) >>>> + return; >>> >>> Don't do things that can fail here >> >> Do you mean that as "GFP_ATOMIC" is used, the if branch can be deleted? > > No, don't do allocations at all if you can't allow them to fail. OK, thanks! I will initialize this structure at compile time. > > Jason > > . >