[openib-general] [PATCH] ping: Use Sean's new nifty MAD helper functions

Hal Rosenstock halr at voltaire.com
Wed Apr 27 11:49:24 PDT 2005


ping: Use Sean's new nifty MAD helper functions
Also, minor cleanup during startup and shutdown

Signed-off-by: Hal Rosenstock <halr at voltaire.com>

Note that the patch below addresses a litle more than half of Roland's
comments on this. The TODO list for this is:
1. finish addressing comments
2. wire MAD changes (discussed on list)
3. support for RMPP

Index: ping.c
===================================================================
--- ping.c	(revision 2212)
+++ ping.c	(working copy)
@@ -40,9 +40,20 @@
 #include <linux/utsname.h>
 #include <asm/bug.h>
 
-#include "ping_priv.h"
-#include "mad_priv.h"
+#include <ib_mad.h>
 
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION("kernel IB ping agent");
+MODULE_AUTHOR("Shahar Frank");
+
+#define SPFX "ib_ping: "
+
+struct ib_ping_port_private {
+	struct list_head port_list;
+	int port_num;
+	struct ib_mad_agent *pingd_agent;     /* OpenIB Ping class */
+};
+
 static spinlock_t ib_ping_port_list_lock;
 static LIST_HEAD(ib_ping_port_list);
 
@@ -86,172 +97,79 @@
 	return entry;
 }
 
-static int ping_mad_send(struct ib_mad_agent *mad_agent,
-			 struct ib_ping_port_private *port_priv,
-			 struct ib_mad_private *mad_priv,
-			 struct ib_grh *grh,
-			 struct ib_wc *wc)
-{
-	struct ib_ping_send_wr *ping_send_wr;
-	struct ib_sge gather_list;
-	struct ib_send_wr send_wr;
-	struct ib_send_wr *bad_send_wr;
-	struct ib_ah_attr ah_attr;
-	unsigned long flags;
-	int ret = 1;
-
-	ping_send_wr = kmalloc(sizeof(*ping_send_wr), GFP_KERNEL);
-	if (!ping_send_wr)
-		goto out;
-	ping_send_wr->mad = mad_priv;
-
-	/* PCI mapping */
-	gather_list.addr = dma_map_single(mad_agent->device->dma_device,
-					  &mad_priv->mad,
-					  sizeof(mad_priv->mad),
-					  DMA_TO_DEVICE);
-	gather_list.length = sizeof(mad_priv->mad);
-	gather_list.lkey = mad_agent->mr->lkey;
-
-	send_wr.next = NULL;
-	send_wr.opcode = IB_WR_SEND;
-	send_wr.sg_list = &gather_list;
-	send_wr.num_sge = 1;
-	send_wr.wr.ud.remote_qpn = wc->src_qp; /* DQPN */
-	send_wr.wr.ud.timeout_ms = 0;
-	send_wr.send_flags = IB_SEND_SIGNALED | IB_SEND_SOLICITED;
-
-	ah_attr.dlid = wc->slid;
-	ah_attr.port_num = mad_agent->port_num;
-	ah_attr.src_path_bits = wc->dlid_path_bits;
-	ah_attr.sl = wc->sl;
-	ah_attr.static_rate = 0;
-	ah_attr.ah_flags = 0; /* No GRH */
-	if (mad_priv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_OPENIB_PING) {
-		if (wc->wc_flags & IB_WC_GRH) {
-			ah_attr.ah_flags = IB_AH_GRH;
-			/* Should sgid be looked up ? */
-			ah_attr.grh.sgid_index = 0;
-			ah_attr.grh.hop_limit = grh->hop_limit;
-			ah_attr.grh.flow_label = be32_to_cpu(
-				grh->version_tclass_flow)  & 0xfffff;
-			ah_attr.grh.traffic_class = (be32_to_cpu(
-				grh->version_tclass_flow) >> 20) & 0xff;
-			memcpy(ah_attr.grh.dgid.raw,
-			       grh->sgid.raw,
-			       sizeof(ah_attr.grh.dgid));
-		}
-	} else {
-		printk(KERN_ERR SPFX "Not OpenIB ping class 0x%x\n",
-		       mad_priv->mad.mad.mad_hdr.mgmt_class);
-		kfree(ping_send_wr);
-		goto out;
-	}
-
-	ping_send_wr->ah = ib_create_ah(mad_agent->qp->pd, &ah_attr);
-	if (IS_ERR(ping_send_wr->ah)) {
-		printk(KERN_ERR SPFX "No memory for address handle\n");
-		kfree(ping_send_wr);
-		goto out;
-	}
-
-	send_wr.wr.ud.ah = ping_send_wr->ah;
-	send_wr.wr.ud.pkey_index = wc->pkey_index;
-	send_wr.wr.ud.remote_qkey = IB_QP1_QKEY;
-	send_wr.wr.ud.mad_hdr = &mad_priv->mad.mad.mad_hdr;
-	send_wr.wr_id = (unsigned long)ping_send_wr;
-
-	pci_unmap_addr_set(ping_send_wr, mapping, gather_list.addr);
-
-	/* Send */
-	spin_lock_irqsave(&port_priv->send_list_lock, flags);
-	if (ib_post_send_mad(mad_agent, &send_wr, &bad_send_wr)) {
-		spin_unlock_irqrestore(&port_priv->send_list_lock, flags);
-		dma_unmap_single(mad_agent->device->dma_device,
-				 pci_unmap_addr(ping_send_wr, mapping),
-				 sizeof(mad_priv->mad),
-				 DMA_TO_DEVICE);
-		ib_destroy_ah(ping_send_wr->ah);
-		kfree(ping_send_wr);
-	} else {
-		list_add_tail(&ping_send_wr->send_list,
-			      &port_priv->send_posted_list);
-		spin_unlock_irqrestore(&port_priv->send_list_lock, flags);
-		ret = 0;
-	}
-
-out:
-	return ret;
-}
-
 static void pingd_recv_handler(struct ib_mad_agent *mad_agent,
 			       struct ib_mad_recv_wc *mad_recv_wc)
 {
-	struct ib_ping_port_private	*port_priv;
-	struct ib_vendor_mad	*vend;
-	struct ib_mad_private *recv = container_of(mad_recv_wc,
-					struct ib_mad_private,
-					header.recv_wc);
+	struct ib_ping_port_private *port_priv;
+	struct ib_ah *ah;
+	struct ib_mad_send_buf *msg;
+	struct ib_vendor_mad *vend;
+	struct ib_send_wr *bad_send_wr;
+	int ret;
 
 	/* Find matching MAD agent */
 	port_priv = ib_get_ping_port(NULL, 0, mad_agent);
 	if (!port_priv) {
-		kmem_cache_free(ib_mad_cache, recv);
 		printk(KERN_ERR SPFX "pingd_recv_handler: no matching MAD "
 		       "agent %p\n", mad_agent);
-		return;
+		goto error1;
 	}
 
-	vend = (struct ib_vendor_mad *)mad_recv_wc->recv_buf.mad;
+	ah = ib_create_ah_from_wc(mad_agent->qp->pd, mad_recv_wc->wc,
+				  mad_recv_wc->recv_buf.grh,
+				  mad_agent->port_num);
+	if (IS_ERR(ah)) {
+		printk(KERN_ERR SPFX "pingd_recv_handler: failed to create AH from recv WC\n");
+		goto error1;
+	}
 
+	msg = ib_create_send_mad(mad_agent, mad_recv_wc->wc->src_qp,
+				 mad_recv_wc->wc->pkey_index, ah,
+				 offsetof(struct ib_vendor_mad, data),
+				 mad_recv_wc->mad_len -
+					offsetof(struct ib_vendor_mad, data),
+				 GFP_KERNEL);
+	if (IS_ERR(msg)) {
+		printk(KERN_ERR SPFX "pingd_recv_handler: failed to create response MAD\n");
+		goto error2;
+	}
+
+	vend = (struct ib_vendor_mad *) msg->mad;
+	memcpy(vend, mad_recv_wc->recv_buf.mad, sizeof(*vend));
 	vend->mad_hdr.method |= IB_MGMT_METHOD_RESP;
 	vend->mad_hdr.status = 0;
 	if (!system_utsname.domainname[0])
 		strncpy(vend->data, system_utsname.nodename, sizeof vend->data);
 	else
 		snprintf(vend->data, sizeof vend->data, "%s.%s",
-			system_utsname.nodename, system_utsname.domainname);
+			 system_utsname.nodename, system_utsname.domainname);
 
 	/* Send response */
-	if (ping_mad_send(mad_agent, port_priv, recv,
-			  mad_recv_wc->recv_buf.grh, mad_recv_wc->wc)) {
-		kmem_cache_free(ib_mad_cache, recv);
-		printk(KERN_ERR SPFX "pingd_recv_handler: reply failed\n");
+	ret = ib_post_send_mad(mad_agent, &msg->send_wr, &bad_send_wr);
+	if (!ret) {
+		ib_free_recv_mad(mad_recv_wc);
+		return;
 	}
+
+	ib_free_send_mad(msg);
+	printk(KERN_ERR SPFX "pingd_recv_handler: reply failed\n");
+
+error2:
+	ib_destroy_ah(ah);
+error1:
+	ib_free_recv_mad(mad_recv_wc);
 }
 
 static void pingd_send_handler(struct ib_mad_agent *mad_agent,
 			       struct ib_mad_send_wc *mad_send_wc)
 {
-	struct ib_ping_port_private	*port_priv;
-	struct ib_ping_send_wr		*ping_send_wr;
-	unsigned long			flags;
+	struct ib_mad_send_buf *msg;
 
-	/* Find matching MAD agent */
-	port_priv = ib_get_ping_port(NULL, 0, mad_agent);
-	if (!port_priv) {
-		printk(KERN_ERR SPFX "pingd_send_handler: no matching MAD "
-		       "agent %p\n", mad_agent);
-		return;
-	}
-
-	ping_send_wr = (struct ib_ping_send_wr *)(unsigned long)mad_send_wc->wr_id;
-	spin_lock_irqsave(&port_priv->send_list_lock, flags);
-	/* Remove completed send from posted send MAD list */
-	list_del(&ping_send_wr->send_list);
-	spin_unlock_irqrestore(&port_priv->send_list_lock, flags);
-
-	/* Unmap PCI */
-	dma_unmap_single(mad_agent->device->dma_device,
-			 pci_unmap_addr(ping_send_wr, mapping),
-			 sizeof(ping_send_wr->mad->mad),
-			 DMA_TO_DEVICE);
-
-	ib_destroy_ah(ping_send_wr->ah);
-
-	/* Release allocated memory */
-	kmem_cache_free(ib_mad_cache, ping_send_wr->mad);
-	kfree(ping_send_wr);
+	msg = (struct ib_mad_send_buf *) (unsigned long) mad_send_wc->wr_id;
+	ib_destroy_ah(msg->send_wr.wr.ud.ah);
+	if (mad_send_wc->status != IB_WC_SUCCESS)
+		printk(KERN_ERR SPFX "pingd_send_handler: Error sending MAD: %d\n", mad_send_wc->status);
+	ib_free_send_mad(msg);
 }
 
 static int ib_ping_port_open(struct ib_device *device, int port_num)
@@ -261,14 +179,6 @@
 	struct ib_mad_reg_req pingd_reg_req;
 	unsigned long flags;
 
-	/* First, check if port already open */
-	port_priv = ib_get_ping_port(device, port_num, NULL);
-	if (port_priv) {
-		printk(KERN_DEBUG SPFX "%s port %d already open\n",
-		       device->name, port_num);
-		return 0;
-	}
-
 	/* Create new device info */
 	port_priv = kmalloc(sizeof *port_priv, GFP_KERNEL);
 	if (!port_priv) {
@@ -279,9 +189,6 @@
 
 	memset(port_priv, 0, sizeof *port_priv);
 	port_priv->port_num = port_num;
-	spin_lock_init(&port_priv->send_list_lock);
-	INIT_LIST_HEAD(&port_priv->send_posted_list);
-
 	pingd_reg_req.mgmt_class = IB_MGMT_CLASS_OPENIB_PING;
 	pingd_reg_req.mgmt_class_version = 1;
 	pingd_reg_req.oui[0] = (IB_OPENIB_OUI >> 16) & 0xff;
@@ -336,7 +243,7 @@
 
 static void ib_ping_init_device(struct ib_device *device)
 {
-	int ret, num_ports, cur_port, i, ret2;
+	int num_ports, cur_port, i;
 
 	if (device->node_type == IB_NODE_SWITCH) {
 		num_ports = 1;
@@ -347,34 +254,27 @@
 	}
 
 	for (i = 0; i < num_ports; i++, cur_port++) {
-		ret = ib_ping_port_open(device, cur_port);
-		if (ret) {
+		if (ib_ping_port_open(device, cur_port))
 			printk(KERN_ERR SPFX "Couldn't open %s port %d\n",
 			       device->name, cur_port);
 			goto error_device_open;
-		}
 	}
-	goto error_device_query;
+	return;
 
 error_device_open:
 	while (i > 0) {
 		cur_port--;
-		ret2 = ib_ping_port_close(device, cur_port);
-		if (ret2) {
-			printk(KERN_ERR PFX "Couldn't close %s port %d "
+		if (ib_ping_port_close(device, cur_port))
+			printk(KERN_ERR SPFX "Couldn't close %s port %d "
 			       "for ping agent\n",
 			       device->name, cur_port);
-		}
 		i--;
 	}
-
-error_device_query:
-	return;
 }
 
 static void ib_ping_remove_device(struct ib_device *device)
 {
-	int ret = 0, i, num_ports, cur_port, ret2;
+	int i, num_ports, cur_port;
 
 	if (device->node_type == IB_NODE_SWITCH) {
 		num_ports = 1;
@@ -384,14 +284,10 @@
 		cur_port = 1;
 	}
 	for (i = 0; i < num_ports; i++, cur_port++) {
-		ret2 = ib_ping_port_close(device, cur_port);
-		if (ret2) {
+		if (ib_ping_port_close(device, cur_port))
 			printk(KERN_ERR SPFX "Couldn't close %s port %d "
 			       "for ping agent\n",
 			       device->name, cur_port);
-			if (!ret)
-				ret = ret2;
-		}
 	}
 }
 
Index: mad.c
===================================================================
--- mad.c	(revision 2217)
+++ mad.c	(working copy)
@@ -44,7 +44,6 @@
 
 
 kmem_cache_t *ib_mad_cache;
-EXPORT_SYMBOL(ib_mad_cache);
 
 static struct list_head ib_mad_port_list;
 static u32 ib_mad_client_id = 0;
Index: ping_priv.h
===================================================================
--- ping_priv.h	(revision 2212)
+++ ping_priv.h	(working copy)
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2004, 2005 Mellanox Technologies Ltd.  All rights reserved.
- * Copyright (c) 2004, 2005 Infinicon Corporation.  All rights reserved.
- * Copyright (c) 2004, 2005 Intel Corporation.  All rights reserved.
- * Copyright (c) 2004, 2005 Topspin Corporation.  All rights reserved.
- * Copyright (c) 2004, 2005 Voltaire Corporation.  All rights reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses.  You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- *     Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * $Id$
- */
-
-#ifndef __IB_PING_PRIV_H__
-#define __IB_PING_PRIV_H__
-
-#include <linux/pci.h>
-
-#define SPFX "ib_ping: "
-
-struct ib_ping_send_wr {
-	struct list_head send_list;
-	struct ib_ah *ah;
-	struct ib_mad_private *mad;
-	DECLARE_PCI_UNMAP_ADDR(mapping)
-};
-
-struct ib_ping_port_private {
-	struct list_head port_list;
-	struct list_head send_posted_list;
-	spinlock_t send_list_lock;
-	int port_num;
-	struct ib_mad_agent *pingd_agent;     /* OpenIB Ping class */
-};
-
-#endif	/* __IB_PING_PRIV_H__ */






More information about the general mailing list