mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-04 20:19:47 +08:00 
			
		
		
		
	qed: Make OOO archipelagos into an array
No need to maintain the various open archipelagos as a list - The maximal number of them is known, and we can use the CID as key for random-access into the array. Signed-off-by: Michal Kalderon <Michal.Kalderon@caviumc.om> Signed-off-by: Yuval Mintz <Yuval.Mintz@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									2f2b2614e8
								
							
						
					
					
						commit
						1eec2437d1
					
				| @ -41,6 +41,7 @@ | |||||||
| #include "qed_iscsi.h" | #include "qed_iscsi.h" | ||||||
| #include "qed_ll2.h" | #include "qed_ll2.h" | ||||||
| #include "qed_ooo.h" | #include "qed_ooo.h" | ||||||
|  | #include "qed_cxt.h" | ||||||
| 
 | 
 | ||||||
| static struct qed_ooo_archipelago | static struct qed_ooo_archipelago | ||||||
| *qed_ooo_seek_archipelago(struct qed_hwfn *p_hwfn, | *qed_ooo_seek_archipelago(struct qed_hwfn *p_hwfn, | ||||||
| @ -48,15 +49,18 @@ static struct qed_ooo_archipelago | |||||||
| 			  *p_ooo_info, | 			  *p_ooo_info, | ||||||
| 			  u32 cid) | 			  u32 cid) | ||||||
| { | { | ||||||
| 	struct qed_ooo_archipelago *p_archipelago = NULL; | 	u32 idx = (cid & 0xffff) - p_ooo_info->cid_base; | ||||||
| 
 | 	struct qed_ooo_archipelago *p_archipelago; | ||||||
| 	list_for_each_entry(p_archipelago, |  | ||||||
| 			    &p_ooo_info->archipelagos_list, list_entry) { |  | ||||||
| 		if (p_archipelago->cid == cid) |  | ||||||
| 			return p_archipelago; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
|  | 	if (idx >= p_ooo_info->max_num_archipelagos) | ||||||
| 		return NULL; | 		return NULL; | ||||||
|  | 
 | ||||||
|  | 	p_archipelago = &p_ooo_info->p_archipelagos_mem[idx]; | ||||||
|  | 
 | ||||||
|  | 	if (list_empty(&p_archipelago->isles_list)) | ||||||
|  | 		return NULL; | ||||||
|  | 
 | ||||||
|  | 	return p_archipelago; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static struct qed_ooo_isle *qed_ooo_seek_isle(struct qed_hwfn *p_hwfn, | static struct qed_ooo_isle *qed_ooo_seek_isle(struct qed_hwfn *p_hwfn, | ||||||
| @ -97,8 +101,8 @@ void qed_ooo_save_history_entry(struct qed_hwfn *p_hwfn, | |||||||
| 
 | 
 | ||||||
| struct qed_ooo_info *qed_ooo_alloc(struct qed_hwfn *p_hwfn) | struct qed_ooo_info *qed_ooo_alloc(struct qed_hwfn *p_hwfn) | ||||||
| { | { | ||||||
|  | 	u16 max_num_archipelagos = 0, cid_base; | ||||||
| 	struct qed_ooo_info *p_ooo_info; | 	struct qed_ooo_info *p_ooo_info; | ||||||
| 	u16 max_num_archipelagos = 0; |  | ||||||
| 	u16 max_num_isles = 0; | 	u16 max_num_isles = 0; | ||||||
| 	u32 i; | 	u32 i; | ||||||
| 
 | 
 | ||||||
| @ -110,6 +114,7 @@ struct qed_ooo_info *qed_ooo_alloc(struct qed_hwfn *p_hwfn) | |||||||
| 
 | 
 | ||||||
| 	max_num_archipelagos = p_hwfn->pf_params.iscsi_pf_params.num_cons; | 	max_num_archipelagos = p_hwfn->pf_params.iscsi_pf_params.num_cons; | ||||||
| 	max_num_isles = QED_MAX_NUM_ISLES + max_num_archipelagos; | 	max_num_isles = QED_MAX_NUM_ISLES + max_num_archipelagos; | ||||||
|  | 	cid_base = (u16)qed_cxt_get_proto_cid_start(p_hwfn, PROTOCOLID_ISCSI); | ||||||
| 
 | 
 | ||||||
| 	if (!max_num_archipelagos) { | 	if (!max_num_archipelagos) { | ||||||
| 		DP_NOTICE(p_hwfn, | 		DP_NOTICE(p_hwfn, | ||||||
| @ -121,11 +126,12 @@ struct qed_ooo_info *qed_ooo_alloc(struct qed_hwfn *p_hwfn) | |||||||
| 	if (!p_ooo_info) | 	if (!p_ooo_info) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 
 | 
 | ||||||
|  | 	p_ooo_info->cid_base = cid_base; | ||||||
|  | 	p_ooo_info->max_num_archipelagos = max_num_archipelagos; | ||||||
|  | 
 | ||||||
| 	INIT_LIST_HEAD(&p_ooo_info->free_buffers_list); | 	INIT_LIST_HEAD(&p_ooo_info->free_buffers_list); | ||||||
| 	INIT_LIST_HEAD(&p_ooo_info->ready_buffers_list); | 	INIT_LIST_HEAD(&p_ooo_info->ready_buffers_list); | ||||||
| 	INIT_LIST_HEAD(&p_ooo_info->free_isles_list); | 	INIT_LIST_HEAD(&p_ooo_info->free_isles_list); | ||||||
| 	INIT_LIST_HEAD(&p_ooo_info->free_archipelagos_list); |  | ||||||
| 	INIT_LIST_HEAD(&p_ooo_info->archipelagos_list); |  | ||||||
| 
 | 
 | ||||||
| 	p_ooo_info->p_isles_mem = kcalloc(max_num_isles, | 	p_ooo_info->p_isles_mem = kcalloc(max_num_isles, | ||||||
| 					  sizeof(struct qed_ooo_isle), | 					  sizeof(struct qed_ooo_isle), | ||||||
| @ -146,11 +152,8 @@ struct qed_ooo_info *qed_ooo_alloc(struct qed_hwfn *p_hwfn) | |||||||
| 	if (!p_ooo_info->p_archipelagos_mem) | 	if (!p_ooo_info->p_archipelagos_mem) | ||||||
| 		goto no_archipelagos_mem; | 		goto no_archipelagos_mem; | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; i < max_num_archipelagos; i++) { | 	for (i = 0; i < max_num_archipelagos; i++) | ||||||
| 		INIT_LIST_HEAD(&p_ooo_info->p_archipelagos_mem[i].isles_list); | 		INIT_LIST_HEAD(&p_ooo_info->p_archipelagos_mem[i].isles_list); | ||||||
| 		list_add_tail(&p_ooo_info->p_archipelagos_mem[i].list_entry, |  | ||||||
| 			      &p_ooo_info->free_archipelagos_list); |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	p_ooo_info->ooo_history.p_cqes = | 	p_ooo_info->ooo_history.p_cqes = | ||||||
| 				kcalloc(QED_MAX_NUM_OOO_HISTORY_ENTRIES, | 				kcalloc(QED_MAX_NUM_OOO_HISTORY_ENTRIES, | ||||||
| @ -178,21 +181,9 @@ void qed_ooo_release_connection_isles(struct qed_hwfn *p_hwfn, | |||||||
| 	struct qed_ooo_archipelago *p_archipelago; | 	struct qed_ooo_archipelago *p_archipelago; | ||||||
| 	struct qed_ooo_buffer *p_buffer; | 	struct qed_ooo_buffer *p_buffer; | ||||||
| 	struct qed_ooo_isle *p_isle; | 	struct qed_ooo_isle *p_isle; | ||||||
| 	bool b_found = false; |  | ||||||
| 
 | 
 | ||||||
| 	if (list_empty(&p_ooo_info->archipelagos_list)) | 	p_archipelago = qed_ooo_seek_archipelago(p_hwfn, p_ooo_info, cid); | ||||||
| 		return; | 	if (!p_archipelago) | ||||||
| 
 |  | ||||||
| 	list_for_each_entry(p_archipelago, |  | ||||||
| 			    &p_ooo_info->archipelagos_list, list_entry) { |  | ||||||
| 		if (p_archipelago->cid == cid) { |  | ||||||
| 			list_del(&p_archipelago->list_entry); |  | ||||||
| 			b_found = true; |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (!b_found) |  | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	while (!list_empty(&p_archipelago->isles_list)) { | 	while (!list_empty(&p_archipelago->isles_list)) { | ||||||
| @ -216,27 +207,21 @@ void qed_ooo_release_connection_isles(struct qed_hwfn *p_hwfn, | |||||||
| 		list_add_tail(&p_isle->list_entry, | 		list_add_tail(&p_isle->list_entry, | ||||||
| 			      &p_ooo_info->free_isles_list); | 			      &p_ooo_info->free_isles_list); | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	list_add_tail(&p_archipelago->list_entry, |  | ||||||
| 		      &p_ooo_info->free_archipelagos_list); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void qed_ooo_release_all_isles(struct qed_hwfn *p_hwfn, | void qed_ooo_release_all_isles(struct qed_hwfn *p_hwfn, | ||||||
| 			       struct qed_ooo_info *p_ooo_info) | 			       struct qed_ooo_info *p_ooo_info) | ||||||
| { | { | ||||||
| 	struct qed_ooo_archipelago *p_arch; | 	struct qed_ooo_archipelago *p_archipelago; | ||||||
| 	struct qed_ooo_buffer *p_buffer; | 	struct qed_ooo_buffer *p_buffer; | ||||||
| 	struct qed_ooo_isle *p_isle; | 	struct qed_ooo_isle *p_isle; | ||||||
|  | 	u32 i; | ||||||
| 
 | 
 | ||||||
| 	while (!list_empty(&p_ooo_info->archipelagos_list)) { | 	for (i = 0; i < p_ooo_info->max_num_archipelagos; i++) { | ||||||
| 		p_arch = list_first_entry(&p_ooo_info->archipelagos_list, | 		p_archipelago = &(p_ooo_info->p_archipelagos_mem[i]); | ||||||
| 					  struct qed_ooo_archipelago, |  | ||||||
| 					  list_entry); |  | ||||||
| 
 | 
 | ||||||
| 		list_del(&p_arch->list_entry); | 		while (!list_empty(&p_archipelago->isles_list)) { | ||||||
| 
 | 			p_isle = list_first_entry(&p_archipelago->isles_list, | ||||||
| 		while (!list_empty(&p_arch->isles_list)) { |  | ||||||
| 			p_isle = list_first_entry(&p_arch->isles_list, |  | ||||||
| 						  struct qed_ooo_isle, | 						  struct qed_ooo_isle, | ||||||
| 						  list_entry); | 						  list_entry); | ||||||
| 
 | 
 | ||||||
| @ -258,8 +243,6 @@ void qed_ooo_release_all_isles(struct qed_hwfn *p_hwfn, | |||||||
| 			list_add_tail(&p_isle->list_entry, | 			list_add_tail(&p_isle->list_entry, | ||||||
| 				      &p_ooo_info->free_isles_list); | 				      &p_ooo_info->free_isles_list); | ||||||
| 		} | 		} | ||||||
| 		list_add_tail(&p_arch->list_entry, |  | ||||||
| 			      &p_ooo_info->free_archipelagos_list); |  | ||||||
| 	} | 	} | ||||||
| 	if (!list_empty(&p_ooo_info->ready_buffers_list)) | 	if (!list_empty(&p_ooo_info->ready_buffers_list)) | ||||||
| 		list_splice_tail_init(&p_ooo_info->ready_buffers_list, | 		list_splice_tail_init(&p_ooo_info->ready_buffers_list, | ||||||
| @ -378,12 +361,6 @@ void qed_ooo_delete_isles(struct qed_hwfn *p_hwfn, | |||||||
| 		p_ooo_info->cur_isles_number--; | 		p_ooo_info->cur_isles_number--; | ||||||
| 		list_add(&p_isle->list_entry, &p_ooo_info->free_isles_list); | 		list_add(&p_isle->list_entry, &p_ooo_info->free_isles_list); | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	if (list_empty(&p_archipelago->isles_list)) { |  | ||||||
| 		list_del(&p_archipelago->list_entry); |  | ||||||
| 		list_add(&p_archipelago->list_entry, |  | ||||||
| 			 &p_ooo_info->free_archipelagos_list); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void qed_ooo_add_new_isle(struct qed_hwfn *p_hwfn, | void qed_ooo_add_new_isle(struct qed_hwfn *p_hwfn, | ||||||
| @ -426,28 +403,10 @@ void qed_ooo_add_new_isle(struct qed_hwfn *p_hwfn, | |||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (!p_archipelago && | 	if (!p_archipelago) { | ||||||
| 	    !list_empty(&p_ooo_info->free_archipelagos_list)) { | 		u32 idx = (cid & 0xffff) - p_ooo_info->cid_base; | ||||||
| 		p_archipelago = |  | ||||||
| 		    list_first_entry(&p_ooo_info->free_archipelagos_list, |  | ||||||
| 				     struct qed_ooo_archipelago, list_entry); |  | ||||||
| 
 | 
 | ||||||
| 		list_del(&p_archipelago->list_entry); | 		p_archipelago = &p_ooo_info->p_archipelagos_mem[idx]; | ||||||
| 		if (!list_empty(&p_archipelago->isles_list)) { |  | ||||||
| 			DP_NOTICE(p_hwfn, |  | ||||||
| 				  "Free OOO connection is not empty\n"); |  | ||||||
| 			INIT_LIST_HEAD(&p_archipelago->isles_list); |  | ||||||
| 		} |  | ||||||
| 		p_archipelago->cid = cid; |  | ||||||
| 		list_add(&p_archipelago->list_entry, |  | ||||||
| 			 &p_ooo_info->archipelagos_list); |  | ||||||
| 	} else if (!p_archipelago) { |  | ||||||
| 		DP_NOTICE(p_hwfn, "No more free OOO connections\n"); |  | ||||||
| 		list_add(&p_isle->list_entry, |  | ||||||
| 			 &p_ooo_info->free_isles_list); |  | ||||||
| 		list_add(&p_buffer->list_entry, |  | ||||||
| 			 &p_ooo_info->free_buffers_list); |  | ||||||
| 		return; |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	list_add(&p_buffer->list_entry, &p_isle->buffers_list); | 	list_add(&p_buffer->list_entry, &p_isle->buffers_list); | ||||||
| @ -517,11 +476,6 @@ void qed_ooo_join_isles(struct qed_hwfn *p_hwfn, | |||||||
| 	} else { | 	} else { | ||||||
| 		list_splice_tail_init(&p_right_isle->buffers_list, | 		list_splice_tail_init(&p_right_isle->buffers_list, | ||||||
| 				      &p_ooo_info->ready_buffers_list); | 				      &p_ooo_info->ready_buffers_list); | ||||||
| 		if (list_empty(&p_archipelago->isles_list)) { |  | ||||||
| 			list_del(&p_archipelago->list_entry); |  | ||||||
| 			list_add(&p_archipelago->list_entry, |  | ||||||
| 				 &p_ooo_info->free_archipelagos_list); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 	list_add_tail(&p_right_isle->list_entry, &p_ooo_info->free_isles_list); | 	list_add_tail(&p_right_isle->list_entry, &p_ooo_info->free_isles_list); | ||||||
| } | } | ||||||
|  | |||||||
| @ -60,9 +60,7 @@ struct qed_ooo_isle { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct qed_ooo_archipelago { | struct qed_ooo_archipelago { | ||||||
| 	struct list_head list_entry; |  | ||||||
| 	struct list_head isles_list; | 	struct list_head isles_list; | ||||||
| 	u32 cid; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct qed_ooo_history { | struct qed_ooo_history { | ||||||
| @ -75,14 +73,14 @@ struct qed_ooo_info { | |||||||
| 	struct list_head free_buffers_list; | 	struct list_head free_buffers_list; | ||||||
| 	struct list_head ready_buffers_list; | 	struct list_head ready_buffers_list; | ||||||
| 	struct list_head free_isles_list; | 	struct list_head free_isles_list; | ||||||
| 	struct list_head free_archipelagos_list; |  | ||||||
| 	struct list_head archipelagos_list; |  | ||||||
| 	struct qed_ooo_archipelago *p_archipelagos_mem; | 	struct qed_ooo_archipelago *p_archipelagos_mem; | ||||||
| 	struct qed_ooo_isle *p_isles_mem; | 	struct qed_ooo_isle *p_isles_mem; | ||||||
| 	struct qed_ooo_history ooo_history; | 	struct qed_ooo_history ooo_history; | ||||||
| 	u32 cur_isles_number; | 	u32 cur_isles_number; | ||||||
| 	u32 max_isles_number; | 	u32 max_isles_number; | ||||||
| 	u32 gen_isles_number; | 	u32 gen_isles_number; | ||||||
|  | 	u16 max_num_archipelagos; | ||||||
|  | 	u16 cid_base; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #if IS_ENABLED(CONFIG_QED_ISCSI) | #if IS_ENABLED(CONFIG_QED_ISCSI) | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Michal Kalderon
						Michal Kalderon