[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