Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

IB/mad: Enable loopback of DR SMP responses from userspace

The local loopback of an outgoing DR SMP response is limited to those
that originate at the driver specific SMA implementation during the
driver specific process_mad() function. This patch enables a
returning DR SMP originating in userspace (or elsewhere) to be
delivered to the local managment stack. In this specific case the
driver process_mad() function does not consume or process the MAD, so
a reponse mad has not be created and the original MAD must manually be
copied to the MAD buffer that is to be handed off to the local agent.

Signed-off-by: Steve Welch <swelch@systemfabricworks.com>
Acked-by: Hal Rosenstock <hal@xsigo.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>

authored by

Steve Welch and committed by
Roland Dreier
727792da f9b40353

+20 -4
+3 -3
drivers/infiniband/core/mad.c
··· 701 701 } 702 702 703 703 /* Check to post send on QP or process locally */ 704 - if (smi_check_local_smp(smp, device) == IB_SMI_DISCARD) 704 + if (smi_check_local_smp(smp, device) == IB_SMI_DISCARD && 705 + smi_check_local_returning_smp(smp, device) == IB_SMI_DISCARD) 705 706 goto out; 706 707 707 708 local = kmalloc(sizeof *local, GFP_ATOMIC); ··· 753 752 port_priv = ib_get_mad_port(mad_agent_priv->agent.device, 754 753 mad_agent_priv->agent.port_num); 755 754 if (port_priv) { 756 - mad_priv->mad.mad.mad_hdr.tid = 757 - ((struct ib_mad *)smp)->mad_hdr.tid; 755 + memcpy(&mad_priv->mad.mad, smp, sizeof(struct ib_mad)); 758 756 recv_mad_agent = find_mad_agent(port_priv, 759 757 &mad_priv->mad.mad); 760 758 }
+17 -1
drivers/infiniband/core/smi.h
··· 59 59 u8 node_type, int port_num); 60 60 61 61 /* 62 - * Return 1 if the SMP should be handled by the local SMA/SM via process_mad 62 + * Return IB_SMI_HANDLE if the SMP should be handled by the local SMA/SM 63 + * via process_mad 63 64 */ 64 65 static inline enum smi_action smi_check_local_smp(struct ib_smp *smp, 65 66 struct ib_device *device) ··· 72 71 (smp->hop_ptr == smp->hop_cnt + 1)) ? 73 72 IB_SMI_HANDLE : IB_SMI_DISCARD); 74 73 } 74 + 75 + /* 76 + * Return IB_SMI_HANDLE if the SMP should be handled by the local SMA/SM 77 + * via process_mad 78 + */ 79 + static inline enum smi_action smi_check_local_returning_smp(struct ib_smp *smp, 80 + struct ib_device *device) 81 + { 82 + /* C14-13:3 -- We're at the end of the DR segment of path */ 83 + /* C14-13:4 -- Hop Pointer == 0 -> give to SM */ 84 + return ((device->process_mad && 85 + ib_get_smp_direction(smp) && 86 + !smp->hop_ptr) ? IB_SMI_HANDLE : IB_SMI_DISCARD); 87 + } 88 + 75 89 #endif /* __SMI_H_ */