RE: [PATCH v3] IB/mlx4: Fix stale CM id_map entries when RTU is never received
From: Praveen Kannoju
Date: Wed Jul 15 2026 - 04:13:24 EST
Oracle Confidential
I missed rebasing this, Leon.
The conflict was with my earlier patch, +ACI-IB/mlx4: delete allocated id+AF8-map+AF8-entry while sending REJ+ACI-, which is already in rdma-next. I have rebased the fix on top of it and sent v4:
https://lore.kernel.org/linux-rdma/20260715080738.1357072-1-praveen.kannoju+AEA-oracle.com/T/+ACM-u
-
Praveen.
Oracle Confidential
+AD4- -----Original Message-----
+AD4- From: Leon Romanovsky +ADw-leon+AEA-kernel.org+AD4-
+AD4- Sent: Wednesday, July 15, 2026 12:36 PM
+AD4- To: Praveen Kannoju +ADw-praveen.kannoju+AEA-oracle.com+AD4-
+AD4- Cc: yishaih+AEA-nvidia.com+ADs- jgg+AEA-ziepe.ca+ADs- linux-rdma+AEA-vger.kernel.org+ADs- linux-
+AD4- kernel+AEA-vger.kernel.org
+AD4- Subject: Re: +AFs-PATCH v3+AF0- IB/mlx4: Fix stale CM id+AF8-map entries when RTU is
+AD4- never received
+AD4-
+AD4- On Mon, Jul 13, 2026 at 11:11:42AM +-0000, Praveen Kumar Kannoju wrote:
+AD4- +AD4- mlx4+AF8-ib+AF8-multiplex+AF8-cm+AF8-handler() allocates an id+AF8-map+AF8-entry for CM
+AD4- +AD4- transactions, but the entry is normally released only on DREQ or REJ
+AD4- +AD4- flows.
+AD4- +AD4-
+AD4- +AD4- In the duplicate REP handling scenario, cm+AF8-dup+AF8-rep+AF8-handler() may be
+AD4- +AD4- invoked when the remote side receives a REP for which no matching
+AD4- +AD4- cm+AF8-id+AF8-priv exists. In such cases the CM handshake never reaches RTU,
+AD4- +AD4- and the sender side may never receive either DREQ or REJ cleanup events.
+AD4- +AD4-
+AD4- +AD4- As a result, the allocated id+AF8-map+AF8-entry remains indefinitely,
+AD4- +AD4- resulting in a stale mapping leak.
+AD4- +AD4-
+AD4- +AD4- Fix this by arming an RTU-abandon cleanup timeout when the
+AD4- +AD4- id+AF8-map+AF8-entry is allocated. The timeout uses the mlx4 CM workqueue and
+AD4- +AD4- the existing
+AD4- +AD4- schedule+AF8-delayed() path, so later DREQ/REJ cleanup can shorten the
+AD4- +AD4- pending timeout with mod+AF8-delayed+AF8-work().
+AD4- +AD4-
+AD4- +AD4- Track whether a pending cleanup timeout is still waiting for RTU. RTU
+AD4- +AD4- cancels only that initial timeout+ADs- if DREQ/REJ has already converted
+AD4- +AD4- it to normal teardown cleanup, a late or duplicate RTU does not cancel
+AD4- +AD4- the teardown timer. If the RTU timeout callback has already started,
+AD4- +AD4- leave the entry on the timeout path and make the RTU packet lose that race.
+AD4- +AD4-
+AD4- +AD4- Hold id+AF8-map+AF8-lock while looking up the entry, canceling the RTU
+AD4- +AD4- timeout, scheduling teardown cleanup, and copying the id values needed
+AD4- +AD4- by the CM handlers. The delayed-work callback rechecks
+AD4- +AD4- scheduled+AF8-delete under the same lock before removing and freeing the
+AD4- +AD4- entry, avoiding use-after-free when RTU races with timeout execution.
+AD4- +AD4-
+AD4- +AD4- Signed-off-by: Praveen Kumar Kannoju +ADw-praveen.kannoju+AEA-oracle.com+AD4-
+AD4- +AD4- ---
+AD4- +AD4- v1:
+AD4- +AD4- https://lore.kernel.org/linux-rdma/20260507154755.452008-1-
+AD4- praveen.kan
+AD4- +AD4- noju+AEA-oracle.com/T/+ACM-u
+AD4- +AD4- v2:
+AD4- +AD4- https://lore.kernel.org/linux-
+AD4- rdma/BL0PR10MB282074FA0D571F5072DFCB4B8C
+AD4- +AD4- F12+AEA-BL0PR10MB2820.namprd10.prod.outlook.com/T/+ACM-t
+AD4- +AD4-
+AD4- +AD4- Changes in v3:
+AD4- +AD4- - Replace +ACI-Lock should be taken before called+ACI- comments with
+AD4- +AD4- lockdep+AF8-assert+AF8-held(+ACY-sriov-+AD4-id+AF8-map+AF8-lock).
+AD4- +AD4-
+AD4- +AD4- Changes in v2:
+AD4- +AD4- - Queue the RTU-abandon timeout on the mlx4 CM workqueue through
+AD4- +AD4- schedule+AF8-delayed() and use mod+AF8-delayed+AF8-work() so DREQ/REJ cleanup
+AD4- can
+AD4- +AD4- shorten a pending RTU timeout.
+AD4- +AD4- - Track RTU-abandon cleanup separately from normal DREQ/REJ cleanup so
+AD4- a
+AD4- +AD4- late or duplicate RTU does not cancel a teardown timer.
+AD4- +AD4- - Hold id+AF8-map+AF8-lock while looking up id+AF8-map entries, canceling or updating
+AD4- +AD4- delayed work, and copying CM IDs needed by the handlers.
+AD4- +AD4- - Make RTU lose the race when the timeout callback has already started.
+AD4- +AD4-
+AD4- +AD4- drivers/infiniband/hw/mlx4/cm.c +AHw- 98
+AD4- +AD4- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+----------
+AD4- +AD4- 1 file changed, 75 insertions(+-), 23 deletions(-)
+AD4-
+AD4- I wanted to apply this patch, but it has merge conflicts. Please rebase it onto
+AD4- the latest rdma-next.
+AD4-
+AD4- As you are probably the only person using this device in that mode, I will take
+AD4- it as-is after the rebase. Strictly speaking, however, the lock around
+AD4- id+AF8-map+AF8-get() does not make much sense. There is no reference counting on
+AD4- the returned ID, so it can disappear immediately after the lock is released.
+AD4-
+AD4- Thanks.
+AD4-
+AD4- +AD4-
+AD4- +AD4- diff --git a/drivers/infiniband/hw/mlx4/cm.c
+AD4- +AD4- b/drivers/infiniband/hw/mlx4/cm.c index 63a868a..f7905df 100644
+AD4- +AD4- --- a/drivers/infiniband/hw/mlx4/cm.c
+AD4- +AD4- +-+-+- b/drivers/infiniband/hw/mlx4/cm.c
+AD4- +AD4- +AEAAQA- -40,6 +-40,7 +AEAAQA-
+AD4- +AD4- +ACM-include +ACI-mlx4+AF8-ib.h+ACI-
+AD4- +AD4-
+AD4- +AD4- +ACM-define CM+AF8-CLEANUP+AF8-CACHE+AF8-TIMEOUT (30 +ACo- HZ)
+AD4- +AD4- +-+ACM-define CM+AF8-RTU+AF8-TIMEOUT (60 +ACo- HZ)
+AD4- +AD4-
+AD4- +AD4- struct id+AF8-map+AF8-entry +AHs-
+AD4- +AD4- struct rb+AF8-node node+ADs-
+AD4- +AD4- +AEAAQA- -48,6 +-49,7 +AEAAQA- struct id+AF8-map+AF8-entry +AHs-
+AD4- +AD4- u32 pv+AF8-cm+AF8-id+ADs-
+AD4- +AD4- int slave+AF8-id+ADs-
+AD4- +AD4- int scheduled+AF8-delete+ADs-
+AD4- +AD4- +- bool rtu+AF8-timeout+ADs-
+AD4- +AD4- struct mlx4+AF8-ib+AF8-dev +ACo-dev+ADs-
+AD4- +AD4-
+AD4- +AD4- struct list+AF8-head list+ADs-
+AD4- +AD4- +AEAAQA- -184,6 +-186,10 +AEAAQA- static void id+AF8-map+AF8-ent+AF8-timeout(struct
+AD4- work+AF8-struct +ACo-work)
+AD4- +AD4- struct rb+AF8-root +ACo-sl+AF8-id+AF8-map +AD0- +ACY-sriov-+AD4-sl+AF8-id+AF8-map+ADs-
+AD4- +AD4-
+AD4- +AD4- spin+AF8-lock(+ACY-sriov-+AD4-id+AF8-map+AF8-lock)+ADs-
+AD4- +AD4- +- if (+ACE-ent-+AD4-scheduled+AF8-delete) +AHs-
+AD4- +AD4- +- spin+AF8-unlock(+ACY-sriov-+AD4-id+AF8-map+AF8-lock)+ADs-
+AD4- +AD4- +- return+ADs-
+AD4- +AD4- +- +AH0-
+AD4- +AD4- if (+ACE-xa+AF8-erase(+ACY-sriov-+AD4-pv+AF8-id+AF8-table, ent-+AD4-pv+AF8-cm+AF8-id))
+AD4- +AD4- goto out+ADs-
+AD4- +AD4- found+AF8-ent +AD0- id+AF8-map+AF8-find+AF8-by+AF8-sl+AF8-id(+ACY-dev-+AD4-ib+AF8-dev, ent-+AD4-slave+AF8-id,
+AD4- +AD4- ent-+AD4-sl+AF8-cm+AF8-id)+ADs- +AEAAQA- -228,8 +-234,12 +AEAAQA- static void sl+AF8-id+AF8-map+AF8-add(struct
+AD4- ib+AF8-device +ACo-ibdev, struct id+AF8-map+AF8-entry +ACo-new)
+AD4- +AD4- rb+AF8-insert+AF8-color(+ACY-new-+AD4-node, sl+AF8-id+AF8-map)+ADs- +AH0-
+AD4- +AD4-
+AD4- +AD4- +-static void schedule+AF8-delayed(struct ib+AF8-device +ACo-ibdev, struct id+AF8-map+AF8-entry
+AD4- +ACo-id,
+AD4- +AD4- +- unsigned long timeout, bool rtu+AF8-timeout)+ADs-
+AD4- +AD4- +-
+AD4- +AD4- static struct id+AF8-map+AF8-entry +ACo-
+AD4- +AD4- -id+AF8-map+AF8-alloc(struct ib+AF8-device +ACo-ibdev, int slave+AF8-id, u32 sl+AF8-cm+AF8-id)
+AD4- +AD4- +-id+AF8-map+AF8-alloc(struct ib+AF8-device +ACo-ibdev, int slave+AF8-id, u32 sl+AF8-cm+AF8-id,
+AD4- +AD4- +- u32 +ACo-pv+AF8-cm+AF8-id)
+AD4- +AD4- +AHs-
+AD4- +AD4- int ret+ADs-
+AD4- +AD4- struct id+AF8-map+AF8-entry +ACo-ent+ADs-
+AD4- +AD4- +AEAAQA- -242,6 +-252,7 +AEAAQA- id+AF8-map+AF8-alloc(struct ib+AF8-device +ACo-ibdev, int slave+AF8-id,
+AD4- u32 sl+AF8-cm+AF8-id)
+AD4- +AD4- ent-+AD4-sl+AF8-cm+AF8-id +AD0- sl+AF8-cm+AF8-id+ADs-
+AD4- +AD4- ent-+AD4-slave+AF8-id +AD0- slave+AF8-id+ADs-
+AD4- +AD4- ent-+AD4-scheduled+AF8-delete +AD0- 0+ADs-
+AD4- +AD4- +- ent-+AD4-rtu+AF8-timeout +AD0- false+ADs-
+AD4- +AD4- ent-+AD4-dev +AD0- to+AF8-mdev(ibdev)+ADs-
+AD4- +AD4- INIT+AF8-DELAYED+AF8-WORK(+ACY-ent-+AD4-timeout, id+AF8-map+AF8-ent+AF8-timeout)+ADs-
+AD4- +AD4-
+AD4- +AD4- +AEAAQA- -251,6 +-262,8 +AEAAQA- id+AF8-map+AF8-alloc(struct ib+AF8-device +ACo-ibdev, int slave+AF8-id,
+AD4- u32 sl+AF8-cm+AF8-id)
+AD4- +AD4- spin+AF8-lock(+ACY-sriov-+AD4-id+AF8-map+AF8-lock)+ADs-
+AD4- +AD4- sl+AF8-id+AF8-map+AF8-add(ibdev, ent)+ADs-
+AD4- +AD4- list+AF8-add+AF8-tail(+ACY-ent-+AD4-list, +ACY-sriov-+AD4-cm+AF8-list)+ADs-
+AD4- +AD4- +- +ACo-pv+AF8-cm+AF8-id +AD0- ent-+AD4-pv+AF8-cm+AF8-id+ADs-
+AD4- +AD4- +- schedule+AF8-delayed(ibdev, ent, CM+AF8-RTU+AF8-TIMEOUT, true)+ADs-
+AD4- +AD4- spin+AF8-unlock(+ACY-sriov-+AD4-id+AF8-map+AF8-lock)+ADs-
+AD4- +AD4- return ent+ADs-
+AD4- +AD4- +AH0-
+AD4- +AD4- +AEAAQA- -261,48 +-274,47 +AEAAQA- id+AF8-map+AF8-alloc(struct ib+AF8-device +ACo-ibdev, int
+AD4- slave+AF8-id, u32 sl+AF8-cm+AF8-id)
+AD4- +AD4- return ERR+AF8-PTR(-ENOMEM)+ADs-
+AD4- +AD4- +AH0-
+AD4- +AD4-
+AD4- +AD4- static struct id+AF8-map+AF8-entry +ACo-
+AD4- +AD4- id+AF8-map+AF8-get(struct ib+AF8-device +ACo-ibdev, int +ACo-pv+AF8-cm+AF8-id, int slave+AF8-id, int
+AD4- +AD4- sl+AF8-cm+AF8-id) +AHs-
+AD4- +AD4- struct id+AF8-map+AF8-entry +ACo-ent+ADs-
+AD4- +AD4- struct mlx4+AF8-ib+AF8-sriov +ACo-sriov +AD0- +ACY-to+AF8-mdev(ibdev)-+AD4-sriov+ADs-
+AD4- +AD4-
+AD4- +AD4- - spin+AF8-lock(+ACY-sriov-+AD4-id+AF8-map+AF8-lock)+ADs-
+AD4- +AD4- +- lockdep+AF8-assert+AF8-held(+ACY-sriov-+AD4-id+AF8-map+AF8-lock)+ADs-
+AD4- +AD4- if (+ACo-pv+AF8-cm+AF8-id +AD0APQ- -1) +AHs-
+AD4- +AD4- ent +AD0- id+AF8-map+AF8-find+AF8-by+AF8-sl+AF8-id(ibdev, slave+AF8-id, sl+AF8-cm+AF8-id)+ADs-
+AD4- +AD4- if (ent)
+AD4- +AD4- +ACo-pv+AF8-cm+AF8-id +AD0- (int) ent-+AD4-pv+AF8-cm+AF8-id+ADs-
+AD4- +AD4- +AH0- else
+AD4- +AD4- ent +AD0- xa+AF8-load(+ACY-sriov-+AD4-pv+AF8-id+AF8-table, +ACo-pv+AF8-cm+AF8-id)+ADs-
+AD4- +AD4- - spin+AF8-unlock(+ACY-sriov-+AD4-id+AF8-map+AF8-lock)+ADs-
+AD4- +AD4-
+AD4- +AD4- return ent+ADs-
+AD4- +AD4- +AH0-
+AD4- +AD4-
+AD4- +AD4- -static void schedule+AF8-delayed(struct ib+AF8-device +ACo-ibdev, struct
+AD4- +AD4- id+AF8-map+AF8-entry +ACo-id)
+AD4- +AD4- +-static void schedule+AF8-delayed(struct ib+AF8-device +ACo-ibdev, struct id+AF8-map+AF8-entry
+AD4- +ACo-id,
+AD4- +AD4- +- unsigned long timeout, bool rtu+AF8-timeout)
+AD4- +AD4- +AHs-
+AD4- +AD4- struct mlx4+AF8-ib+AF8-sriov +ACo-sriov +AD0- +ACY-to+AF8-mdev(ibdev)-+AD4-sriov+ADs-
+AD4- +AD4- unsigned long flags+ADs-
+AD4- +AD4-
+AD4- +AD4- - spin+AF8-lock(+ACY-sriov-+AD4-id+AF8-map+AF8-lock)+ADs-
+AD4- +AD4- +- lockdep+AF8-assert+AF8-held(+ACY-sriov-+AD4-id+AF8-map+AF8-lock)+ADs-
+AD4- +AD4- spin+AF8-lock+AF8-irqsave(+ACY-sriov-+AD4-going+AF8-down+AF8-lock, flags)+ADs-
+AD4- +AD4- /+ACo-make sure that there is no schedule inside the scheduled work.+ACo-/
+AD4- +AD4- - if (+ACE-sriov-+AD4-is+AF8-going+AF8-down +ACYAJg- +ACE-id-+AD4-scheduled+AF8-delete) +AHs-
+AD4- +AD4- +- if (+ACE-sriov-+AD4-is+AF8-going+AF8-down +AHwAfA- id-+AD4-scheduled+AF8-delete) +AHs-
+AD4- +AD4- id-+AD4-scheduled+AF8-delete +AD0- 1+ADs-
+AD4- +AD4- - queue+AF8-delayed+AF8-work(cm+AF8-wq, +ACY-id-+AD4-timeout,
+AD4- CM+AF8-CLEANUP+AF8-CACHE+AF8-TIMEOUT)+ADs-
+AD4- +AD4- - +AH0- else if (id-+AD4-scheduled+AF8-delete) +AHs-
+AD4- +AD4- - /+ACo- Adjust timeout if already scheduled +ACo-/
+AD4- +AD4- - mod+AF8-delayed+AF8-work(cm+AF8-wq, +ACY-id-+AD4-timeout,
+AD4- CM+AF8-CLEANUP+AF8-CACHE+AF8-TIMEOUT)+ADs-
+AD4- +AD4- +- id-+AD4-rtu+AF8-timeout +AD0- rtu+AF8-timeout+ADs-
+AD4- +AD4- +- mod+AF8-delayed+AF8-work(cm+AF8-wq, +ACY-id-+AD4-timeout, timeout)+ADs-
+AD4- +AD4- +AH0-
+AD4- +AD4- spin+AF8-unlock+AF8-irqrestore(+ACY-sriov-+AD4-going+AF8-down+AF8-lock, flags)+ADs-
+AD4- +AD4- - spin+AF8-unlock(+ACY-sriov-+AD4-id+AF8-map+AF8-lock)+ADs-
+AD4- +AD4- +AH0-
+AD4- +AD4-
+AD4- +AD4- +ACM-define REJ+AF8-REASON(m) be16+AF8-to+AF8-cpu(((struct cm+AF8-generic+AF8-msg
+AD4- +AD4- +ACo-)(m))-+AD4-rej+AF8-reason) int mlx4+AF8-ib+AF8-multiplex+AF8-cm+AF8-handler(struct ib+AF8-device
+AD4- +ACo-ibdev, int port, int slave+AF8-id,
+AD4- +AD4- struct ib+AF8-mad +ACo-mad)
+AD4- +AD4- +AHs-
+AD4- +AD4- +- struct mlx4+AF8-ib+AF8-sriov +ACo-sriov +AD0- +ACY-to+AF8-mdev(ibdev)-+AD4-sriov+ADs-
+AD4- +AD4- struct id+AF8-map+AF8-entry +ACo-id+ADs-
+AD4- +AD4- +- u32 pv+AF8-cm+AF8-id+AF8-to+AF8-set +AD0- 0+ADs-
+AD4- +AD4- u32 sl+AF8-cm+AF8-id+ADs-
+AD4- +AD4- int pv+AF8-cm+AF8-id +AD0- -1+ADs-
+AD4- +AD4-
+AD4- +AD4- +AEAAQA- -312,10 +-323,15 +AEAAQA- int mlx4+AF8-ib+AF8-multiplex+AF8-cm+AF8-handler(struct
+AD4- ib+AF8-device +ACo-ibdev, int port, int slave+AF8-id
+AD4- +AD4- mad-+AD4-mad+AF8-hdr.attr+AF8-id +AD0APQ- CM+AF8-SIDR+AF8-REQ+AF8-ATTR+AF8-ID +AHwAfA-
+AD4- +AD4- (mad-+AD4-mad+AF8-hdr.attr+AF8-id +AD0APQ- CM+AF8-REJ+AF8-ATTR+AF8-ID +ACYAJg- REJ+AF8-REASON(mad)
+AD4- +AD0APQ- IB+AF8-CM+AF8-REJ+AF8-TIMEOUT)) +AHs-
+AD4- +AD4- sl+AF8-cm+AF8-id +AD0- get+AF8-local+AF8-comm+AF8-id(mad)+ADs-
+AD4- +AD4- +- spin+AF8-lock(+ACY-sriov-+AD4-id+AF8-map+AF8-lock)+ADs-
+AD4- +AD4- id +AD0- id+AF8-map+AF8-get(ibdev, +ACY-pv+AF8-cm+AF8-id, slave+AF8-id, sl+AF8-cm+AF8-id)+ADs-
+AD4- +AD4- +- if (id)
+AD4- +AD4- +- pv+AF8-cm+AF8-id+AF8-to+AF8-set +AD0- id-+AD4-pv+AF8-cm+AF8-id+ADs-
+AD4- +AD4- +- spin+AF8-unlock(+ACY-sriov-+AD4-id+AF8-map+AF8-lock)+ADs-
+AD4- +AD4- if (id)
+AD4- +AD4- goto cont+ADs-
+AD4- +AD4- - id +AD0- id+AF8-map+AF8-alloc(ibdev, slave+AF8-id, sl+AF8-cm+AF8-id)+ADs-
+AD4- +AD4- +- id +AD0- id+AF8-map+AF8-alloc(ibdev, slave+AF8-id, sl+AF8-cm+AF8-id,
+AD4- +AD4- +- +ACY-pv+AF8-cm+AF8-id+AF8-to+AF8-set)+ADs-
+AD4- +AD4- if (IS+AF8-ERR(id)) +AHs-
+AD4- +AD4- mlx4+AF8-ib+AF8-warn(ibdev, +ACIAJQ-s: id+AHs-slave: +ACU-d, sl+AF8-cm+AF8-id:
+AD4- 0x+ACU-x+AH0- Failed to id+AF8-map+AF8-alloc+AFw-n+ACI-,
+AD4- +AD4- +AF8AXw-func+AF8AXw-, slave+AF8-id, sl+AF8-cm+AF8-id)+ADs-
+AD4- +AD4- +AEAAQA- -326,7 +-342,25 +AEAAQA- int mlx4+AF8-ib+AF8-multiplex+AF8-cm+AF8-handler(struct
+AD4- ib+AF8-device +ACo-ibdev, int port, int slave+AF8-id
+AD4- +AD4- return 0+ADs-
+AD4- +AD4- +AH0- else +AHs-
+AD4- +AD4- sl+AF8-cm+AF8-id +AD0- get+AF8-local+AF8-comm+AF8-id(mad)+ADs-
+AD4- +AD4- +- spin+AF8-lock(+ACY-sriov-+AD4-id+AF8-map+AF8-lock)+ADs-
+AD4- +AD4- id +AD0- id+AF8-map+AF8-get(ibdev, +ACY-pv+AF8-cm+AF8-id, slave+AF8-id, sl+AF8-cm+AF8-id)+ADs-
+AD4- +AD4- +- if (id) +AHs-
+AD4- +AD4- +- if (mad-+AD4-mad+AF8-hdr.attr+AF8-id +AD0APQ- CM+AF8-RTU+AF8-ATTR+AF8-ID +ACYAJg-
+AD4- +AD4- +- id-+AD4-rtu+AF8-timeout) +AHs-
+AD4- +AD4- +- id-+AD4-rtu+AF8-timeout +AD0- false+ADs-
+AD4- +AD4- +- if (cancel+AF8-delayed+AF8-work(+ACY-id-+AD4-timeout))
+AD4- +AD4- +- id-+AD4-scheduled+AF8-delete +AD0- 0+ADs-
+AD4- +AD4- +- else
+AD4- +AD4- +- id +AD0- NULL+ADs-
+AD4- +AD4- +- +AH0-
+AD4- +AD4- +- if (id)
+AD4- +AD4- +- pv+AF8-cm+AF8-id+AF8-to+AF8-set +AD0- id-+AD4-pv+AF8-cm+AF8-id+ADs-
+AD4- +AD4- +- if (id +ACYAJg- mad-+AD4-mad+AF8-hdr.attr+AF8-id +AD0APQ-
+AD4- CM+AF8-DREQ+AF8-ATTR+AF8-ID)
+AD4- +AD4- +- schedule+AF8-delayed(ibdev, id,
+AD4- +AD4- +-
+AD4- CM+AF8-CLEANUP+AF8-CACHE+AF8-TIMEOUT,
+AD4- +AD4- +- false)+ADs-
+AD4- +AD4- +- +AH0-
+AD4- +AD4- +- spin+AF8-unlock(+ACY-sriov-+AD4-id+AF8-map+AF8-lock)+ADs-
+AD4- +AD4- +AH0-
+AD4- +AD4-
+AD4- +AD4- if (+ACE-id) +AHs-
+AD4- +AD4- +AEAAQA- -336,10 +-370,7 +AEAAQA- int mlx4+AF8-ib+AF8-multiplex+AF8-cm+AF8-handler(struct
+AD4- ib+AF8-device +ACo-ibdev, int port, int slave+AF8-id
+AD4- +AD4- +AH0-
+AD4- +AD4-
+AD4- +AD4- cont:
+AD4- +AD4- - set+AF8-local+AF8-comm+AF8-id(mad, id-+AD4-pv+AF8-cm+AF8-id)+ADs-
+AD4- +AD4- -
+AD4- +AD4- - if (mad-+AD4-mad+AF8-hdr.attr+AF8-id +AD0APQ- CM+AF8-DREQ+AF8-ATTR+AF8-ID)
+AD4- +AD4- - schedule+AF8-delayed(ibdev, id)+ADs-
+AD4- +AD4- +- set+AF8-local+AF8-comm+AF8-id(mad, pv+AF8-cm+AF8-id+AF8-to+AF8-set)+ADs-
+AD4- +AD4- return 0+ADs-
+AD4- +AD4- +AH0-
+AD4- +AD4-
+AD4- +AD4- +AEAAQA- -429,7 +-460,10 +AEAAQA- int mlx4+AF8-ib+AF8-demux+AF8-cm+AF8-handler(struct ib+AF8-device
+AD4- +ACo-ibdev, int port, int +ACo-slave,
+AD4- +AD4- struct mlx4+AF8-ib+AF8-sriov +ACo-sriov +AD0- +ACY-to+AF8-mdev(ibdev)-+AD4-sriov+ADs-
+AD4- +AD4- u32 rem+AF8-pv+AF8-cm+AF8-id +AD0- get+AF8-local+AF8-comm+AF8-id(mad)+ADs-
+AD4- +AD4- u32 pv+AF8-cm+AF8-id+ADs-
+AD4- +AD4- +- u32 sl+AF8-cm+AF8-id +AD0- 0+ADs-
+AD4- +AD4- struct id+AF8-map+AF8-entry +ACo-id+ADs-
+AD4- +AD4- +- int pv+AF8-cm+AF8-id+AF8-int+ADs-
+AD4- +AD4- +- int slave+AF8-id +AD0- 0+ADs-
+AD4- +AD4- int sts+ADs-
+AD4- +AD4-
+AD4- +AD4- if (mad-+AD4-mad+AF8-hdr.attr+AF8-id +AD0APQ- CM+AF8-REQ+AF8-ATTR+AF8-ID +AHwAfA- +AEAAQA- -457,7
+AD4- +-491,28 +AEAAQA-
+AD4- +AD4- int mlx4+AF8-ib+AF8-demux+AF8-cm+AF8-handler(struct ib+AF8-device +ACo-ibdev, int port, int +ACo-slave,
+AD4- +AD4- +AH0-
+AD4- +AD4-
+AD4- +AD4- pv+AF8-cm+AF8-id +AD0- get+AF8-remote+AF8-comm+AF8-id(mad)+ADs-
+AD4- +AD4- - id +AD0- id+AF8-map+AF8-get(ibdev, (int +ACo-)+ACY-pv+AF8-cm+AF8-id, -1, -1)+ADs-
+AD4- +AD4- +- pv+AF8-cm+AF8-id+AF8-int +AD0- pv+AF8-cm+AF8-id+ADs-
+AD4- +AD4- +- spin+AF8-lock(+ACY-sriov-+AD4-id+AF8-map+AF8-lock)+ADs-
+AD4- +AD4- +- id +AD0- id+AF8-map+AF8-get(ibdev, +ACY-pv+AF8-cm+AF8-id+AF8-int, -1, -1)+ADs-
+AD4- +AD4- +- if (id) +AHs-
+AD4- +AD4- +- if (mad-+AD4-mad+AF8-hdr.attr+AF8-id +AD0APQ- CM+AF8-RTU+AF8-ATTR+AF8-ID +ACYAJg-
+AD4- +AD4- +- id-+AD4-rtu+AF8-timeout) +AHs-
+AD4- +AD4- +- id-+AD4-rtu+AF8-timeout +AD0- false+ADs-
+AD4- +AD4- +- if (cancel+AF8-delayed+AF8-work(+ACY-id-+AD4-timeout))
+AD4- +AD4- +- id-+AD4-scheduled+AF8-delete +AD0- 0+ADs-
+AD4- +AD4- +- else
+AD4- +AD4- +- id +AD0- NULL+ADs-
+AD4- +AD4- +- +AH0-
+AD4- +AD4- +- if (id +ACYAJg- slave)
+AD4- +AD4- +- slave+AF8-id +AD0- id-+AD4-slave+AF8-id+ADs-
+AD4- +AD4- +- if (id)
+AD4- +AD4- +- sl+AF8-cm+AF8-id +AD0- id-+AD4-sl+AF8-cm+AF8-id+ADs-
+AD4- +AD4- +- if (id +ACYAJg- (mad-+AD4-mad+AF8-hdr.attr+AF8-id +AD0APQ- CM+AF8-DREQ+AF8-ATTR+AF8-ID +AHwAfA-
+AD4- +AD4- +- mad-+AD4-mad+AF8-hdr.attr+AF8-id +AD0APQ- CM+AF8-REJ+AF8-ATTR+AF8-ID))
+AD4- +AD4- +- schedule+AF8-delayed(ibdev, id,
+AD4- +AD4- +- CM+AF8-CLEANUP+AF8-CACHE+AF8-TIMEOUT,
+AD4- false)+ADs-
+AD4- +AD4- +- +AH0-
+AD4- +AD4- +- spin+AF8-unlock(+ACY-sriov-+AD4-id+AF8-map+AF8-lock)+ADs-
+AD4- +AD4-
+AD4- +AD4- if (+ACE-id) +AHs-
+AD4- +AD4- if (mad-+AD4-mad+AF8-hdr.attr+AF8-id +AD0APQ- CM+AF8-REJ+AF8-ATTR+AF8-ID +ACYAJg- +AEAAQA- -
+AD4- 472,12 +-527,8 +AEAAQA-
+AD4- +AD4- int mlx4+AF8-ib+AF8-demux+AF8-cm+AF8-handler(struct ib+AF8-device +ACo-ibdev, int port, int +ACo-slave,
+AD4- +AD4- +AH0-
+AD4- +AD4-
+AD4- +AD4- if (slave)
+AD4- +AD4- - +ACo-slave +AD0- id-+AD4-slave+AF8-id+ADs-
+AD4- +AD4- - set+AF8-remote+AF8-comm+AF8-id(mad, id-+AD4-sl+AF8-cm+AF8-id)+ADs-
+AD4- +AD4- -
+AD4- +AD4- - if (mad-+AD4-mad+AF8-hdr.attr+AF8-id +AD0APQ- CM+AF8-DREQ+AF8-ATTR+AF8-ID +AHwAfA-
+AD4- +AD4- - mad-+AD4-mad+AF8-hdr.attr+AF8-id +AD0APQ- CM+AF8-REJ+AF8-ATTR+AF8-ID)
+AD4- +AD4- - schedule+AF8-delayed(ibdev, id)+ADs-
+AD4- +AD4- +- +ACo-slave +AD0- slave+AF8-id+ADs-
+AD4- +AD4- +- set+AF8-remote+AF8-comm+AF8-id(mad, sl+AF8-cm+AF8-id)+ADs-
+AD4- +AD4-
+AD4- +AD4- return 0+ADs-
+AD4- +AD4- +AH0-