Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ba1b54bd authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm:ipa3: fix the header table gap issue"

parents 54114a39 7d6b2039
Loading
Loading
Loading
Loading
+41 −67
Original line number Diff line number Diff line
@@ -1249,8 +1249,9 @@ int ipa2_reset_hdr(bool user_only)
	struct ipa_hdr_offset_entry *off_next;
	struct ipa_hdr_proc_ctx_offset_entry *ctx_off_entry;
	struct ipa_hdr_proc_ctx_offset_entry *ctx_off_next;
	int i, end = 0;
	bool user_rule = false;
	struct ipa_hdr_tbl *htbl = &ipa_ctx->hdr_tbl;
	struct ipa_hdr_proc_ctx_tbl *htbl_proc = &ipa_ctx->hdr_proc_ctx_tbl;
	int i;

	/*
	 * issue a reset on the routing module since routing rules point to
@@ -1288,8 +1289,6 @@ int ipa2_reset_hdr(bool user_only)
			return -EFAULT;
		}

		if (entry->ipacm_installed)
			user_rule = true;
		if (!user_only || entry->ipacm_installed) {
			if (entry->is_hdr_proc_ctx) {
				dma_unmap_single(ipa_ctx->pdev,
@@ -1297,9 +1296,15 @@ int ipa2_reset_hdr(bool user_only)
					entry->hdr_len,
					DMA_TO_DEVICE);
				entry->proc_ctx = NULL;
			} else {
				/* move the offset entry to free list */
				entry->offset_entry->ipacm_installed = 0;
				list_move(&entry->offset_entry->link,
				&htbl->head_free_offset_list[
					entry->offset_entry->bin]);
			}
			list_del(&entry->link);
			ipa_ctx->hdr_tbl.hdr_cnt--;
			htbl->hdr_cnt--;
			entry->ref_cnt = 0;
			entry->cookie = 0;

@@ -1308,53 +1313,37 @@ int ipa2_reset_hdr(bool user_only)
			kmem_cache_free(ipa_ctx->hdr_cache, entry);
		}
	}

	/* only clean up offset_list and free_offset_list on global reset */
	if (!user_only) {
		for (i = 0; i < IPA_HDR_BIN_MAX; i++) {
			list_for_each_entry_safe(off_entry, off_next,
				&ipa_ctx->hdr_tbl.head_offset_list[i],
				link) {

			/*
			 * do not remove the default exception header which is
			 * at offset 0
				/**
				 * do not remove the default exception
				 * header which is at offset 0
				 */
				if (off_entry->offset == 0)
					continue;

			if (!user_only ||
					off_entry->ipacm_installed) {
				list_del(&off_entry->link);
				kmem_cache_free(ipa_ctx->hdr_offset_cache,
					off_entry);
			} else {
				if (off_entry->offset +
					ipa_hdr_bin_sz[off_entry->bin] > end) {
					end = off_entry->offset +
						ipa_hdr_bin_sz[off_entry->bin];
					IPADBG("replace end = %d\n", end);
				}
			}
			}
			list_for_each_entry_safe(off_entry, off_next,
				&ipa_ctx->hdr_tbl.head_free_offset_list[i],
				link) {

			if (!user_only ||
					off_entry->ipacm_installed) {
				list_del(&off_entry->link);
				kmem_cache_free(ipa_ctx->hdr_offset_cache,
					off_entry);
			}
		}
		/* there is one header of size 8 */
		ipa_ctx->hdr_tbl.end = 8;
		ipa_ctx->hdr_tbl.hdr_cnt = 1;
	}

	IPADBG("hdr_tbl.end = %d\n", end);
	if (user_rule) {
		ipa_ctx->hdr_tbl.end = end;
		IPADBG("hdr_tbl.end = %d\n", end);
	}
	IPADBG("reset hdr proc ctx\n");
	user_rule = false;
	end = 0;
	list_for_each_entry_safe(
		ctx_entry,
		ctx_next,
@@ -1363,16 +1352,18 @@ int ipa2_reset_hdr(bool user_only)

		if (ipa_id_find(ctx_entry->id) == NULL) {
			mutex_unlock(&ipa_ctx->lock);
			WARN_ON(1);
			WARN_ON_RATELIMIT_IPA(1);
			return -EFAULT;
		}

		if (entry->ipacm_installed)
			user_rule = true;
		if (!user_only ||
				ctx_entry->ipacm_installed) {
			/* move the offset entry to appropriate free list */
			list_move(&ctx_entry->offset_entry->link,
				&htbl_proc->head_free_offset_list[
					ctx_entry->offset_entry->bin]);
			list_del(&ctx_entry->link);
			ipa_ctx->hdr_proc_ctx_tbl.proc_ctx_cnt--;
			htbl_proc->proc_ctx_cnt--;
			ctx_entry->ref_cnt = 0;
			ctx_entry->cookie = 0;

@@ -1382,47 +1373,30 @@ int ipa2_reset_hdr(bool user_only)
				ctx_entry);
		}
	}
	/* only clean up offset_list and free_offset_list on global reset */
	if (!user_only) {
		for (i = 0; i < IPA_HDR_PROC_CTX_BIN_MAX; i++) {
			list_for_each_entry_safe(ctx_off_entry, ctx_off_next,
				&ipa_ctx->hdr_proc_ctx_tbl.head_offset_list[i],
				link) {

			if (!user_only ||
					ctx_off_entry->ipacm_installed) {
				list_del(&ctx_off_entry->link);
				kmem_cache_free(
					ipa_ctx->hdr_proc_ctx_offset_cache,
					ctx_off_entry);
			} else {
				if (ctx_off_entry->offset +
				ipa_hdr_bin_sz[ctx_off_entry->bin]
				> end) {
					end = ctx_off_entry->offset +
					ipa_hdr_bin_sz[ctx_off_entry->bin];
					IPADBG("replace hdr_proc as %d\n", end);
				}
			}
			}
			list_for_each_entry_safe(ctx_off_entry, ctx_off_next,
			    &ipa_ctx->hdr_proc_ctx_tbl.head_free_offset_list[i],
			    link) {

			if (!user_only ||
					ctx_off_entry->ipacm_installed) {
				&ipa_ctx->hdr_proc_ctx_tbl.
				head_free_offset_list[i], link) {
				list_del(&ctx_off_entry->link);
				kmem_cache_free(
					ipa_ctx->hdr_proc_ctx_offset_cache,
					ctx_off_entry);
			}
		}
		ipa_ctx->hdr_proc_ctx_tbl.end = 0;
		ipa_ctx->hdr_proc_ctx_tbl.proc_ctx_cnt = 0;
	}

	IPADBG("hdr_proc_tbl.end = %d\n", end);
	if (user_rule) {
		ipa_ctx->hdr_proc_ctx_tbl.end = end;
		IPADBG("hdr_proc_tbl.end = %d\n", end);
	}
	mutex_unlock(&ipa_ctx->lock);

	/* commit the change to IPA-HW */
	if (ipa_ctx->ctrl->ipa_commit_hdr()) {
+41 −67
Original line number Diff line number Diff line
@@ -1007,8 +1007,9 @@ int ipa3_reset_hdr(bool user_only)
	struct ipa_hdr_offset_entry *off_next;
	struct ipa3_hdr_proc_ctx_offset_entry *ctx_off_entry;
	struct ipa3_hdr_proc_ctx_offset_entry *ctx_off_next;
	int i, end = 0;
	bool user_rule = false;
	struct ipa3_hdr_tbl *htbl = &ipa3_ctx->hdr_tbl;
	struct ipa3_hdr_proc_ctx_tbl *htbl_proc = &ipa3_ctx->hdr_proc_ctx_tbl;
	int i;

	/*
	 * issue a reset on the routing module since routing rules point to
@@ -1046,8 +1047,6 @@ int ipa3_reset_hdr(bool user_only)
			return -EFAULT;
		}

		if (entry->ipacm_installed)
			user_rule = true;
		if (!user_only || entry->ipacm_installed) {
			if (entry->is_hdr_proc_ctx) {
				dma_unmap_single(ipa3_ctx->pdev,
@@ -1055,9 +1054,15 @@ int ipa3_reset_hdr(bool user_only)
					entry->hdr_len,
					DMA_TO_DEVICE);
				entry->proc_ctx = NULL;
			} else {
				/* move the offset entry to free list */
				entry->offset_entry->ipacm_installed = 0;
				list_move(&entry->offset_entry->link,
				&htbl->head_free_offset_list[
					entry->offset_entry->bin]);
			}
			list_del(&entry->link);
			ipa3_ctx->hdr_tbl.hdr_cnt--;
			htbl->hdr_cnt--;
			entry->ref_cnt = 0;
			entry->cookie = 0;
			/* remove the handle from the database */
@@ -1065,54 +1070,37 @@ int ipa3_reset_hdr(bool user_only)
			kmem_cache_free(ipa3_ctx->hdr_cache, entry);
		}
	}

	/* only clean up offset_list and free_offset_list on global reset */
	if (!user_only) {
		for (i = 0; i < IPA_HDR_BIN_MAX; i++) {
			list_for_each_entry_safe(off_entry, off_next,
					 &ipa3_ctx->hdr_tbl.head_offset_list[i],
					 link) {

			/*
			 * do not remove the default exception header which is
			 * at offset 0
				/**
				 * do not remove the default exception
				 * header which is at offset 0
				 */
				if (off_entry->offset == 0)
					continue;

			if (!user_only ||
					off_entry->ipacm_installed) {
				list_del(&off_entry->link);
				kmem_cache_free(ipa3_ctx->hdr_offset_cache,
					off_entry);
			} else {
				if (off_entry->offset +
					ipa_hdr_bin_sz[off_entry->bin] > end) {
					end = off_entry->offset +
						ipa_hdr_bin_sz[off_entry->bin];
						IPADBG("replace end = %d\n",
								end);
				}
			}
			}
			list_for_each_entry_safe(off_entry, off_next,
				&ipa3_ctx->hdr_tbl.head_free_offset_list[i],
				link) {

			if (!user_only ||
					off_entry->ipacm_installed) {
				list_del(&off_entry->link);
				kmem_cache_free(ipa3_ctx->hdr_offset_cache,
					off_entry);
			}
		}
		/* there is one header of size 8 */
		ipa3_ctx->hdr_tbl.end = 8;
		ipa3_ctx->hdr_tbl.hdr_cnt = 1;
	}

	IPADBG("hdr_tbl.end = %d\n", end);
	if (user_rule) {
		ipa3_ctx->hdr_tbl.end = end;
		IPADBG("hdr_tbl.end = %d\n", end);
	}
	IPADBG("reset hdr proc ctx\n");
	user_rule = false;
	end = 0;
	list_for_each_entry_safe(
		ctx_entry,
		ctx_next,
@@ -1125,12 +1113,14 @@ int ipa3_reset_hdr(bool user_only)
			return -EFAULT;
		}

		if (entry->ipacm_installed)
			user_rule = true;
		if (!user_only ||
				ctx_entry->ipacm_installed) {
			/* move the offset entry to appropriate free list */
			list_move(&ctx_entry->offset_entry->link,
				&htbl_proc->head_free_offset_list[
					ctx_entry->offset_entry->bin]);
			list_del(&ctx_entry->link);
			ipa3_ctx->hdr_proc_ctx_tbl.proc_ctx_cnt--;
			htbl_proc->proc_ctx_cnt--;
			ctx_entry->ref_cnt = 0;
			ctx_entry->cookie = 0;

@@ -1140,45 +1130,29 @@ int ipa3_reset_hdr(bool user_only)
				ctx_entry);
		}
	}

	/* only clean up offset_list and free_offset_list on global reset */
	if (!user_only) {
		for (i = 0; i < IPA_HDR_PROC_CTX_BIN_MAX; i++) {
			list_for_each_entry_safe(ctx_off_entry, ctx_off_next,
				&ipa3_ctx->hdr_proc_ctx_tbl.head_offset_list[i],
				link) {

			if (!user_only ||
					ctx_off_entry->ipacm_installed) {
				list_del(&ctx_off_entry->link);
				kmem_cache_free(
					ipa3_ctx->hdr_proc_ctx_offset_cache,
					ctx_off_entry);
			} else {
				if (ctx_off_entry->offset +
					ipa_hdr_bin_sz[ctx_off_entry->bin]
					> end) {
					end = ctx_off_entry->offset +
					ipa_hdr_bin_sz[ctx_off_entry->bin];
					IPADBG("replace hdr_proc as %d\n", end);
				}
			}
			}
			list_for_each_entry_safe(ctx_off_entry, ctx_off_next,
			&ipa3_ctx->hdr_proc_ctx_tbl.head_free_offset_list[i],
			link) {

			if (!user_only ||
					ctx_off_entry->ipacm_installed) {
				&ipa3_ctx->hdr_proc_ctx_tbl.
				head_free_offset_list[i], link) {
				list_del(&ctx_off_entry->link);
				kmem_cache_free(
					ipa3_ctx->hdr_proc_ctx_offset_cache,
					ctx_off_entry);
			}
		}
	}

	IPADBG("hdr_proc_tbl.end = %d\n", end);
	if (user_rule) {
		ipa3_ctx->hdr_proc_ctx_tbl.end = end;
		IPADBG("hdr_proc_tbl.end = %d\n", end);
		ipa3_ctx->hdr_proc_ctx_tbl.end = 0;
		ipa3_ctx->hdr_proc_ctx_tbl.proc_ctx_cnt = 0;
	}

	/* commit the change to IPA-HW */