mirror of
https://github.com/torvalds/linux.git
synced 2024-11-02 10:11:36 +00:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband: IB/mlx4: Incorrect semicolon after if statement mlx4_core: Wait 1 second after reset before accessing device IPoIB: Fix leak in ipoib_transport_dev_init() error path IB/mlx4: Fix opcode returned in RDMA read completion IB/srp: Add OUI for new Cisco targets IB/srp: Wrap OUI checking for workarounds in helper functions RDMA/cxgb3: Always call low level send function via cxgb3_ofld_send() IB: Move the macro IB_UMEM_MAX_PAGE_CHUNK() to umem.c IB: Include <linux/list.h> and <linux/rwsem.h> from <rdma/ib_verbs.h> IB: Include <linux/list.h> from <rdma/ib_mad.h> IB/mad: Fix address handle leak in mad_rmpp IB/mad: agent_send_response() should be void IB/mad: Fix memory leak in switch handling in ib_mad_recv_done_handler() IB/mad: Fix error path if response alloc fails in ib_mad_recv_done_handler() IB/sa: Don't need to check for default P_Key twice IB/core: Ignore membership bit in ib_find_pkey()
This commit is contained in:
commit
e4f3b1e74b
@ -78,15 +78,14 @@ ib_get_agent_port(struct ib_device *device, int port_num)
|
||||
return entry;
|
||||
}
|
||||
|
||||
int agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
|
||||
struct ib_wc *wc, struct ib_device *device,
|
||||
int port_num, int qpn)
|
||||
void agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
|
||||
struct ib_wc *wc, struct ib_device *device,
|
||||
int port_num, int qpn)
|
||||
{
|
||||
struct ib_agent_port_private *port_priv;
|
||||
struct ib_mad_agent *agent;
|
||||
struct ib_mad_send_buf *send_buf;
|
||||
struct ib_ah *ah;
|
||||
int ret;
|
||||
struct ib_mad_send_wr_private *mad_send_wr;
|
||||
|
||||
if (device->node_type == RDMA_NODE_IB_SWITCH)
|
||||
@ -96,23 +95,21 @@ int agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
|
||||
|
||||
if (!port_priv) {
|
||||
printk(KERN_ERR SPFX "Unable to find port agent\n");
|
||||
return -ENODEV;
|
||||
return;
|
||||
}
|
||||
|
||||
agent = port_priv->agent[qpn];
|
||||
ah = ib_create_ah_from_wc(agent->qp->pd, wc, grh, port_num);
|
||||
if (IS_ERR(ah)) {
|
||||
ret = PTR_ERR(ah);
|
||||
printk(KERN_ERR SPFX "ib_create_ah_from_wc error:%d\n", ret);
|
||||
return ret;
|
||||
printk(KERN_ERR SPFX "ib_create_ah_from_wc error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
send_buf = ib_create_send_mad(agent, wc->src_qp, wc->pkey_index, 0,
|
||||
IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
|
||||
GFP_KERNEL);
|
||||
if (IS_ERR(send_buf)) {
|
||||
ret = PTR_ERR(send_buf);
|
||||
printk(KERN_ERR SPFX "ib_create_send_mad error:%d\n", ret);
|
||||
printk(KERN_ERR SPFX "ib_create_send_mad error\n");
|
||||
goto err1;
|
||||
}
|
||||
|
||||
@ -126,16 +123,15 @@ int agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
|
||||
mad_send_wr->send_wr.wr.ud.port_num = port_num;
|
||||
}
|
||||
|
||||
if ((ret = ib_post_send_mad(send_buf, NULL))) {
|
||||
printk(KERN_ERR SPFX "ib_post_send_mad error:%d\n", ret);
|
||||
if (ib_post_send_mad(send_buf, NULL)) {
|
||||
printk(KERN_ERR SPFX "ib_post_send_mad error\n");
|
||||
goto err2;
|
||||
}
|
||||
return 0;
|
||||
return;
|
||||
err2:
|
||||
ib_free_send_mad(send_buf);
|
||||
err1:
|
||||
ib_destroy_ah(ah);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void agent_send_handler(struct ib_mad_agent *mad_agent,
|
||||
|
@ -46,8 +46,8 @@ extern int ib_agent_port_open(struct ib_device *device, int port_num);
|
||||
|
||||
extern int ib_agent_port_close(struct ib_device *device, int port_num);
|
||||
|
||||
extern int agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
|
||||
struct ib_wc *wc, struct ib_device *device,
|
||||
int port_num, int qpn);
|
||||
extern void agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
|
||||
struct ib_wc *wc, struct ib_device *device,
|
||||
int port_num, int qpn);
|
||||
|
||||
#endif /* __AGENT_H_ */
|
||||
|
@ -702,7 +702,7 @@ int ib_find_pkey(struct ib_device *device,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (pkey == tmp_pkey) {
|
||||
if ((pkey & 0x7fff) == (tmp_pkey & 0x7fff)) {
|
||||
*index = i;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1842,16 +1842,11 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
|
||||
{
|
||||
struct ib_mad_qp_info *qp_info;
|
||||
struct ib_mad_private_header *mad_priv_hdr;
|
||||
struct ib_mad_private *recv, *response;
|
||||
struct ib_mad_private *recv, *response = NULL;
|
||||
struct ib_mad_list_head *mad_list;
|
||||
struct ib_mad_agent_private *mad_agent;
|
||||
int port_num;
|
||||
|
||||
response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL);
|
||||
if (!response)
|
||||
printk(KERN_ERR PFX "ib_mad_recv_done_handler no memory "
|
||||
"for response buffer\n");
|
||||
|
||||
mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id;
|
||||
qp_info = mad_list->mad_queue->qp_info;
|
||||
dequeue_mad(mad_list);
|
||||
@ -1879,6 +1874,13 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
|
||||
if (!validate_mad(&recv->mad.mad, qp_info->qp->qp_num))
|
||||
goto out;
|
||||
|
||||
response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL);
|
||||
if (!response) {
|
||||
printk(KERN_ERR PFX "ib_mad_recv_done_handler no memory "
|
||||
"for response buffer\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (port_priv->device->node_type == RDMA_NODE_IB_SWITCH)
|
||||
port_num = wc->port_num;
|
||||
else
|
||||
@ -1914,12 +1916,11 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
|
||||
response->header.recv_wc.recv_buf.mad = &response->mad.mad;
|
||||
response->header.recv_wc.recv_buf.grh = &response->grh;
|
||||
|
||||
if (!agent_send_response(&response->mad.mad,
|
||||
&response->grh, wc,
|
||||
port_priv->device,
|
||||
smi_get_fwd_port(&recv->mad.smp),
|
||||
qp_info->qp->qp_num))
|
||||
response = NULL;
|
||||
agent_send_response(&response->mad.mad,
|
||||
&response->grh, wc,
|
||||
port_priv->device,
|
||||
smi_get_fwd_port(&recv->mad.smp),
|
||||
qp_info->qp->qp_num);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
@ -163,8 +163,10 @@ static struct ib_mad_send_buf *alloc_response_msg(struct ib_mad_agent *agent,
|
||||
hdr_len, 0, GFP_KERNEL);
|
||||
if (IS_ERR(msg))
|
||||
ib_destroy_ah(ah);
|
||||
else
|
||||
else {
|
||||
msg->ah = ah;
|
||||
msg->context[0] = ah;
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
@ -197,9 +199,7 @@ static void ack_ds_ack(struct ib_mad_agent_private *agent,
|
||||
|
||||
void ib_rmpp_send_handler(struct ib_mad_send_wc *mad_send_wc)
|
||||
{
|
||||
struct ib_rmpp_mad *rmpp_mad = mad_send_wc->send_buf->mad;
|
||||
|
||||
if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_ACK)
|
||||
if (mad_send_wc->send_buf->context[0] == mad_send_wc->send_buf->ah)
|
||||
ib_destroy_ah(mad_send_wc->send_buf->ah);
|
||||
ib_free_send_mad(mad_send_wc->send_buf);
|
||||
}
|
||||
|
@ -385,9 +385,7 @@ static void update_sm_ah(struct work_struct *work)
|
||||
|
||||
new_ah->pkey_index = 0;
|
||||
if (ib_find_pkey(port->agent->device, port->port_num,
|
||||
IB_DEFAULT_PKEY_FULL, &new_ah->pkey_index) &&
|
||||
ib_find_pkey(port->agent->device, port->port_num,
|
||||
IB_DEFAULT_PKEY_PARTIAL, &new_ah->pkey_index))
|
||||
IB_DEFAULT_PKEY_FULL, &new_ah->pkey_index))
|
||||
printk(KERN_ERR "Couldn't find index for default PKey\n");
|
||||
|
||||
memset(&ah_attr, 0, sizeof ah_attr);
|
||||
|
@ -40,6 +40,11 @@
|
||||
|
||||
#include "uverbs.h"
|
||||
|
||||
#define IB_UMEM_MAX_PAGE_CHUNK \
|
||||
((PAGE_SIZE - offsetof(struct ib_umem_chunk, page_list)) / \
|
||||
((void *) &((struct ib_umem_chunk *) 0)->page_list[1] - \
|
||||
(void *) &((struct ib_umem_chunk *) 0)->page_list[0]))
|
||||
|
||||
static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int dirty)
|
||||
{
|
||||
struct ib_umem_chunk *chunk, *tmp;
|
||||
|
@ -139,7 +139,7 @@ static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb)
|
||||
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
|
||||
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, hwtid));
|
||||
skb->priority = CPL_PRIORITY_SETUP;
|
||||
tdev->send(tdev, skb);
|
||||
cxgb3_ofld_send(tdev, skb);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -161,7 +161,7 @@ int iwch_quiesce_tid(struct iwch_ep *ep)
|
||||
req->val = cpu_to_be64(1 << S_TCB_RX_QUIESCE);
|
||||
|
||||
skb->priority = CPL_PRIORITY_DATA;
|
||||
ep->com.tdev->send(ep->com.tdev, skb);
|
||||
cxgb3_ofld_send(ep->com.tdev, skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -183,7 +183,7 @@ int iwch_resume_tid(struct iwch_ep *ep)
|
||||
req->val = 0;
|
||||
|
||||
skb->priority = CPL_PRIORITY_DATA;
|
||||
ep->com.tdev->send(ep->com.tdev, skb);
|
||||
cxgb3_ofld_send(ep->com.tdev, skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -784,7 +784,7 @@ static int update_rx_credits(struct iwch_ep *ep, u32 credits)
|
||||
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, ep->hwtid));
|
||||
req->credit_dack = htonl(V_RX_CREDITS(credits) | V_RX_FORCE_ACK(1));
|
||||
skb->priority = CPL_PRIORITY_ACK;
|
||||
ep->com.tdev->send(ep->com.tdev, skb);
|
||||
cxgb3_ofld_send(ep->com.tdev, skb);
|
||||
return credits;
|
||||
}
|
||||
|
||||
@ -1152,7 +1152,7 @@ static int listen_start(struct iwch_listen_ep *ep)
|
||||
req->opt1 = htonl(V_CONN_POLICY(CPL_CONN_POLICY_ASK));
|
||||
|
||||
skb->priority = 1;
|
||||
ep->com.tdev->send(ep->com.tdev, skb);
|
||||
cxgb3_ofld_send(ep->com.tdev, skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1186,7 +1186,7 @@ static int listen_stop(struct iwch_listen_ep *ep)
|
||||
req->cpu_idx = 0;
|
||||
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, ep->stid));
|
||||
skb->priority = 1;
|
||||
ep->com.tdev->send(ep->com.tdev, skb);
|
||||
cxgb3_ofld_send(ep->com.tdev, skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1264,7 +1264,7 @@ static void reject_cr(struct t3cdev *tdev, u32 hwtid, __be32 peer_ip,
|
||||
rpl->opt0l_status = htonl(CPL_PASS_OPEN_REJECT);
|
||||
rpl->opt2 = 0;
|
||||
rpl->rsvd = rpl->opt2;
|
||||
tdev->send(tdev, skb);
|
||||
cxgb3_ofld_send(tdev, skb);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1557,7 +1557,7 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
|
||||
rpl->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
|
||||
OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid));
|
||||
rpl->cmd = CPL_ABORT_NO_RST;
|
||||
ep->com.tdev->send(ep->com.tdev, rpl_skb);
|
||||
cxgb3_ofld_send(ep->com.tdev, rpl_skb);
|
||||
if (state != ABORTING) {
|
||||
state_set(&ep->com, DEAD);
|
||||
release_ep_resources(ep);
|
||||
|
@ -389,7 +389,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
|
||||
wc->opcode = IB_WC_SEND;
|
||||
break;
|
||||
case MLX4_OPCODE_RDMA_READ:
|
||||
wc->opcode = IB_WC_SEND;
|
||||
wc->opcode = IB_WC_RDMA_READ;
|
||||
wc->byte_len = be32_to_cpu(cqe->byte_cnt);
|
||||
break;
|
||||
case MLX4_OPCODE_ATOMIC_CS:
|
||||
|
@ -109,7 +109,7 @@ int mlx4_MAD_IFC(struct mlx4_ib_dev *dev, int ignore_mkey, int ignore_bkey,
|
||||
in_modifier, op_modifier,
|
||||
MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C);
|
||||
|
||||
if (!err);
|
||||
if (!err)
|
||||
memcpy(response_mad, outmailbox->buf, 256);
|
||||
|
||||
mlx4_free_cmd_mailbox(dev->dev, inmailbox);
|
||||
|
@ -211,6 +211,7 @@ out_free_cq:
|
||||
|
||||
out_free_mr:
|
||||
ib_dereg_mr(priv->mr);
|
||||
ipoib_cm_dev_cleanup(dev);
|
||||
|
||||
out_free_pd:
|
||||
ib_dealloc_pd(priv->pd);
|
||||
|
@ -75,16 +75,12 @@ module_param(topspin_workarounds, int, 0444);
|
||||
MODULE_PARM_DESC(topspin_workarounds,
|
||||
"Enable workarounds for Topspin/Cisco SRP target bugs if != 0");
|
||||
|
||||
static const u8 topspin_oui[3] = { 0x00, 0x05, 0xad };
|
||||
|
||||
static int mellanox_workarounds = 1;
|
||||
|
||||
module_param(mellanox_workarounds, int, 0444);
|
||||
MODULE_PARM_DESC(mellanox_workarounds,
|
||||
"Enable workarounds for Mellanox SRP target bugs if != 0");
|
||||
|
||||
static const u8 mellanox_oui[3] = { 0x00, 0x02, 0xc9 };
|
||||
|
||||
static void srp_add_one(struct ib_device *device);
|
||||
static void srp_remove_one(struct ib_device *device);
|
||||
static void srp_completion(struct ib_cq *cq, void *target_ptr);
|
||||
@ -108,6 +104,24 @@ static const char *srp_target_info(struct Scsi_Host *host)
|
||||
return host_to_target(host)->target_name;
|
||||
}
|
||||
|
||||
static int srp_target_is_topspin(struct srp_target_port *target)
|
||||
{
|
||||
static const u8 topspin_oui[3] = { 0x00, 0x05, 0xad };
|
||||
static const u8 cisco_oui[3] = { 0x00, 0x1b, 0x0d };
|
||||
|
||||
return topspin_workarounds &&
|
||||
(!memcmp(&target->ioc_guid, topspin_oui, sizeof topspin_oui) ||
|
||||
!memcmp(&target->ioc_guid, cisco_oui, sizeof cisco_oui));
|
||||
}
|
||||
|
||||
static int srp_target_is_mellanox(struct srp_target_port *target)
|
||||
{
|
||||
static const u8 mellanox_oui[3] = { 0x00, 0x02, 0xc9 };
|
||||
|
||||
return mellanox_workarounds &&
|
||||
!memcmp(&target->ioc_guid, mellanox_oui, sizeof mellanox_oui);
|
||||
}
|
||||
|
||||
static struct srp_iu *srp_alloc_iu(struct srp_host *host, size_t size,
|
||||
gfp_t gfp_mask,
|
||||
enum dma_data_direction direction)
|
||||
@ -360,7 +374,7 @@ static int srp_send_req(struct srp_target_port *target)
|
||||
* zero out the first 8 bytes of our initiator port ID and set
|
||||
* the second 8 bytes to the local node GUID.
|
||||
*/
|
||||
if (topspin_workarounds && !memcmp(&target->ioc_guid, topspin_oui, 3)) {
|
||||
if (srp_target_is_topspin(target)) {
|
||||
printk(KERN_DEBUG PFX "Topspin/Cisco initiator port ID workaround "
|
||||
"activated for target GUID %016llx\n",
|
||||
(unsigned long long) be64_to_cpu(target->ioc_guid));
|
||||
@ -585,8 +599,8 @@ static int srp_map_fmr(struct srp_target_port *target, struct scatterlist *scat,
|
||||
if (!dev->fmr_pool)
|
||||
return -ENODEV;
|
||||
|
||||
if ((ib_sg_dma_address(ibdev, &scat[0]) & ~dev->fmr_page_mask) &&
|
||||
mellanox_workarounds && !memcmp(&target->ioc_guid, mellanox_oui, 3))
|
||||
if (srp_target_is_mellanox(target) &&
|
||||
(ib_sg_dma_address(ibdev, &scat[0]) & ~dev->fmr_page_mask))
|
||||
return -EINVAL;
|
||||
|
||||
len = page_cnt = 0;
|
||||
@ -1087,8 +1101,7 @@ static void srp_cm_rej_handler(struct ib_cm_id *cm_id,
|
||||
break;
|
||||
|
||||
case IB_CM_REJ_PORT_REDIRECT:
|
||||
if (topspin_workarounds &&
|
||||
!memcmp(&target->ioc_guid, topspin_oui, 3)) {
|
||||
if (srp_target_is_topspin(target)) {
|
||||
/*
|
||||
* Topspin/Cisco SRP gateways incorrectly send
|
||||
* reject reason code 25 when they mean 24
|
||||
|
@ -119,6 +119,9 @@ int mlx4_reset(struct mlx4_dev *dev)
|
||||
writel(MLX4_RESET_VALUE, reset + MLX4_RESET_OFFSET);
|
||||
iounmap(reset);
|
||||
|
||||
/* Docs say to wait one second before accessing device */
|
||||
msleep(1000);
|
||||
|
||||
end = jiffies + MLX4_RESET_TIMEOUT_JIFFIES;
|
||||
do {
|
||||
if (!pci_read_config_word(dev->pdev, PCI_VENDOR_ID, &vendor) &&
|
||||
|
@ -39,6 +39,8 @@
|
||||
#if !defined( IB_MAD_H )
|
||||
#define IB_MAD_H
|
||||
|
||||
#include <linux/list.h>
|
||||
|
||||
#include <rdma/ib_verbs.h>
|
||||
|
||||
/* Management base version */
|
||||
|
@ -46,6 +46,8 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/rwsem.h>
|
||||
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/scatterlist.h>
|
||||
@ -731,11 +733,6 @@ struct ib_udata {
|
||||
size_t outlen;
|
||||
};
|
||||
|
||||
#define IB_UMEM_MAX_PAGE_CHUNK \
|
||||
((PAGE_SIZE - offsetof(struct ib_umem_chunk, page_list)) / \
|
||||
((void *) &((struct ib_umem_chunk *) 0)->page_list[1] - \
|
||||
(void *) &((struct ib_umem_chunk *) 0)->page_list[0]))
|
||||
|
||||
struct ib_pd {
|
||||
struct ib_device *device;
|
||||
struct ib_uobject *uobject;
|
||||
|
Loading…
Reference in New Issue
Block a user