mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	IB/SA: Check dlid before SA agent queries for ClassPortInfo
SA queries SM for class port info when there is a LID_CHANGE event.
When a base lid is configured before fm is started ie when smlid is
not yet assigned, SA handles the LID_CHANGE event and tries query SM
with lid 0. This will cause an hang.
[ 1106.958820] INFO: task kworker/2:0:23 blocked for more than 120 seconds.
[ 1106.965082] Tainted: G O 4.12.0+ #1
[ 1106.969602] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables
 this message.
[ 1106.977227] kworker/2:0 D 0 23 2 0x00000000
[ 1106.977250] Workqueue: infiniband update_ib_cpi [ib_core]
[ 1106.977261] Call Trace:
[ 1106.977273] __schedule+0x28e/0x860
[ 1106.977285] schedule+0x36/0x80
[ 1106.977298] schedule_timeout+0x1a3/0x2e0
[ 1106.977310] ? radix_tree_iter_tag_clear+0x1b/0x20
[ 1106.977322] ? idr_alloc+0x64/0x90
[ 1106.977334] wait_for_completion+0xe3/0x140
[ 1106.977347] ? wake_up_q+0x80/0x80
[ 1106.977369] update_ib_cpi+0x163/0x210 [ib_core]
[ 1106.977381] process_one_work+0x147/0x370
[ 1106.977394] worker_thread+0x4a/0x390
[ 1106.977406] kthread+0x109/0x140
[ 1106.977418] ? process_one_work+0x370/0x370
[ 1106.977430] ? kthread_park+0x60/0x60
[ 1106.977443] ret_from_fork+0x22/0x30
Always ensure a proper smlid is assigned before querying SM for cpi.
Fixes: ee1c60b1bf ("IB/SA: Modify SA to implicitly cache Class Port info")
Reviewed-by: Ira Weiny <ira.weiny@intel.com>
Signed-off-by: Venkata Sandeep Dhanalakota <venkata.s.dhanalakota@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
			
			
This commit is contained in:
		
							parent
							
								
									adb1c0d15e
								
							
						
					
					
						commit
						af808ece5c
					
				
					 2 changed files with 26 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -1345,6 +1345,7 @@ EXPORT_SYMBOL(ib_init_ah_attr_from_path);
 | 
			
		|||
 | 
			
		||||
static int alloc_mad(struct ib_sa_query *query, gfp_t gfp_mask)
 | 
			
		||||
{
 | 
			
		||||
	struct rdma_ah_attr ah_attr;
 | 
			
		||||
	unsigned long flags;
 | 
			
		||||
 | 
			
		||||
	spin_lock_irqsave(&query->port->ah_lock, flags);
 | 
			
		||||
| 
						 | 
				
			
			@ -1356,6 +1357,15 @@ static int alloc_mad(struct ib_sa_query *query, gfp_t gfp_mask)
 | 
			
		|||
	query->sm_ah = query->port->sm_ah;
 | 
			
		||||
	spin_unlock_irqrestore(&query->port->ah_lock, flags);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Always check if sm_ah has valid dlid assigned,
 | 
			
		||||
	 * before querying for class port info
 | 
			
		||||
	 */
 | 
			
		||||
	if ((rdma_query_ah(query->sm_ah->ah, &ah_attr) < 0) ||
 | 
			
		||||
	    !rdma_is_valid_unicast_lid(&ah_attr)) {
 | 
			
		||||
		kref_put(&query->sm_ah->ref, free_sm_ah);
 | 
			
		||||
		return -EAGAIN;
 | 
			
		||||
	}
 | 
			
		||||
	query->mad_buf = ib_create_send_mad(query->port->agent, 1,
 | 
			
		||||
					    query->sm_ah->pkey_index,
 | 
			
		||||
					    0, IB_MGMT_SA_HDR, IB_MGMT_SA_DATA,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -114,4 +114,20 @@ static inline u32 opa_get_mcast_base(u32 nr_top_bits)
 | 
			
		|||
	return (be32_to_cpu(OPA_LID_PERMISSIVE) << (32 - nr_top_bits));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Check for a valid unicast LID for non-SM traffic types */
 | 
			
		||||
static inline bool rdma_is_valid_unicast_lid(struct rdma_ah_attr *attr)
 | 
			
		||||
{
 | 
			
		||||
	if (attr->type == RDMA_AH_ATTR_TYPE_IB) {
 | 
			
		||||
		if (!rdma_ah_get_dlid(attr) ||
 | 
			
		||||
		    rdma_ah_get_dlid(attr) >=
 | 
			
		||||
		    be32_to_cpu(IB_MULTICAST_LID_BASE))
 | 
			
		||||
			return false;
 | 
			
		||||
	} else if (attr->type == RDMA_AH_ATTR_TYPE_OPA) {
 | 
			
		||||
		if (!rdma_ah_get_dlid(attr) ||
 | 
			
		||||
		    rdma_ah_get_dlid(attr) >=
 | 
			
		||||
		    opa_get_mcast_base(OPA_MCAST_NR))
 | 
			
		||||
			return false;
 | 
			
		||||
	}
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
#endif /* OPA_ADDR_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue