lib: sbi_tlb: Reduce size of struct sbi_tlb_info

Let us reduce the size of struct sbi_tlb_info by doing the
following:
1) Change the data type of asid and vmid fields to uint16_t
2) Replace local_fn() function pointer with an enum

Based on the above, the size of struct sbi_tlb_info is reduced
by 16 bytes on RV64 and 4 bytes on RV32.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
This commit is contained in:
Anup Patel
2023-12-11 13:26:49 +05:30
committed by Anup Patel
parent 3daac8fb87
commit 416ceb3cd7
4 changed files with 77 additions and 57 deletions

View File

@@ -34,7 +34,7 @@ static void tlb_flush_all(void)
__asm__ __volatile("sfence.vma");
}
void sbi_tlb_local_hfence_vvma(struct sbi_tlb_info *tinfo)
static void sbi_tlb_local_hfence_vvma(struct sbi_tlb_info *tinfo)
{
unsigned long start = tinfo->start;
unsigned long size = tinfo->size;
@@ -59,7 +59,7 @@ done:
csr_write(CSR_HGATP, hgatp);
}
void sbi_tlb_local_hfence_gvma(struct sbi_tlb_info *tinfo)
static void sbi_tlb_local_hfence_gvma(struct sbi_tlb_info *tinfo)
{
unsigned long start = tinfo->start;
unsigned long size = tinfo->size;
@@ -77,7 +77,7 @@ void sbi_tlb_local_hfence_gvma(struct sbi_tlb_info *tinfo)
}
}
void sbi_tlb_local_sfence_vma(struct sbi_tlb_info *tinfo)
static void sbi_tlb_local_sfence_vma(struct sbi_tlb_info *tinfo)
{
unsigned long start = tinfo->start;
unsigned long size = tinfo->size;
@@ -98,7 +98,7 @@ void sbi_tlb_local_sfence_vma(struct sbi_tlb_info *tinfo)
}
}
void sbi_tlb_local_hfence_vvma_asid(struct sbi_tlb_info *tinfo)
static void sbi_tlb_local_hfence_vvma_asid(struct sbi_tlb_info *tinfo)
{
unsigned long start = tinfo->start;
unsigned long size = tinfo->size;
@@ -124,7 +124,7 @@ done:
csr_write(CSR_HGATP, hgatp);
}
void sbi_tlb_local_hfence_gvma_vmid(struct sbi_tlb_info *tinfo)
static void sbi_tlb_local_hfence_gvma_vmid(struct sbi_tlb_info *tinfo)
{
unsigned long start = tinfo->start;
unsigned long size = tinfo->size;
@@ -143,7 +143,7 @@ void sbi_tlb_local_hfence_gvma_vmid(struct sbi_tlb_info *tinfo)
}
}
void sbi_tlb_local_sfence_vma_asid(struct sbi_tlb_info *tinfo)
static void sbi_tlb_local_sfence_vma_asid(struct sbi_tlb_info *tinfo)
{
unsigned long start = tinfo->start;
unsigned long size = tinfo->size;
@@ -169,32 +169,43 @@ void sbi_tlb_local_sfence_vma_asid(struct sbi_tlb_info *tinfo)
}
}
void sbi_tlb_local_fence_i(struct sbi_tlb_info *tinfo)
static void sbi_tlb_local_fence_i(struct sbi_tlb_info *tinfo)
{
sbi_pmu_ctr_incr_fw(SBI_PMU_FW_FENCE_I_RECVD);
__asm__ __volatile("fence.i");
}
static void tlb_pmu_incr_fw_ctr(struct sbi_tlb_info *data)
static void tlb_entry_local_process(struct sbi_tlb_info *data)
{
if (unlikely(!data))
return;
if (data->local_fn == sbi_tlb_local_fence_i)
sbi_pmu_ctr_incr_fw(SBI_PMU_FW_FENCE_I_SENT);
else if (data->local_fn == sbi_tlb_local_sfence_vma)
sbi_pmu_ctr_incr_fw(SBI_PMU_FW_SFENCE_VMA_SENT);
else if (data->local_fn == sbi_tlb_local_sfence_vma_asid)
sbi_pmu_ctr_incr_fw(SBI_PMU_FW_SFENCE_VMA_ASID_SENT);
else if (data->local_fn == sbi_tlb_local_hfence_gvma)
sbi_pmu_ctr_incr_fw(SBI_PMU_FW_HFENCE_GVMA_SENT);
else if (data->local_fn == sbi_tlb_local_hfence_gvma_vmid)
sbi_pmu_ctr_incr_fw(SBI_PMU_FW_HFENCE_GVMA_VMID_SENT);
else if (data->local_fn == sbi_tlb_local_hfence_vvma)
sbi_pmu_ctr_incr_fw(SBI_PMU_FW_HFENCE_VVMA_SENT);
else if (data->local_fn == sbi_tlb_local_hfence_vvma_asid)
sbi_pmu_ctr_incr_fw(SBI_PMU_FW_HFENCE_VVMA_ASID_SENT);
switch (data->type) {
case SBI_TLB_FENCE_I:
sbi_tlb_local_fence_i(data);
break;
case SBI_TLB_SFENCE_VMA:
sbi_tlb_local_sfence_vma(data);
break;
case SBI_TLB_SFENCE_VMA_ASID:
sbi_tlb_local_sfence_vma_asid(data);
break;
case SBI_TLB_HFENCE_GVMA_VMID:
sbi_tlb_local_hfence_gvma_vmid(data);
break;
case SBI_TLB_HFENCE_GVMA:
sbi_tlb_local_hfence_gvma(data);
break;
case SBI_TLB_HFENCE_VVMA_ASID:
sbi_tlb_local_hfence_vvma_asid(data);
break;
case SBI_TLB_HFENCE_VVMA:
sbi_tlb_local_hfence_vvma(data);
break;
default:
break;
};
}
static void tlb_entry_process(struct sbi_tlb_info *tinfo)
@@ -203,7 +214,7 @@ static void tlb_entry_process(struct sbi_tlb_info *tinfo)
struct sbi_scratch *rscratch = NULL;
atomic_t *rtlb_sync = NULL;
tinfo->local_fn(tinfo);
tlb_entry_local_process(tinfo);
sbi_hartmask_for_each_hartindex(rindex, &tinfo->smask) {
rscratch = sbi_hartindex_to_scratch(rindex);
@@ -305,12 +316,12 @@ static int tlb_update_cb(void *in, void *data)
curr = (struct sbi_tlb_info *)data;
next = (struct sbi_tlb_info *)in;
if (next->local_fn == sbi_tlb_local_sfence_vma_asid &&
curr->local_fn == sbi_tlb_local_sfence_vma_asid) {
if (next->type == SBI_TLB_SFENCE_VMA_ASID &&
curr->type == SBI_TLB_SFENCE_VMA_ASID) {
if (next->asid == curr->asid)
ret = tlb_range_check(curr, next);
} else if (next->local_fn == sbi_tlb_local_sfence_vma &&
curr->local_fn == sbi_tlb_local_sfence_vma) {
} else if (next->type == SBI_TLB_SFENCE_VMA &&
curr->type == SBI_TLB_SFENCE_VMA) {
ret = tlb_range_check(curr, next);
}
@@ -332,7 +343,7 @@ static int tlb_update(struct sbi_scratch *scratch,
* then just do a local flush and return;
*/
if (sbi_hartindex_to_hartid(remote_hartindex) == curr_hartid) {
tinfo->local_fn(tinfo);
tlb_entry_local_process(tinfo);
return SBI_IPI_UPDATE_BREAK;
}
@@ -370,9 +381,19 @@ static struct sbi_ipi_event_ops tlb_ops = {
static u32 tlb_event = SBI_IPI_EVENT_MAX;
static const u32 tlb_type_to_pmu_fw_event[SBI_TLB_TYPE_MAX] = {
[SBI_TLB_FENCE_I] = SBI_PMU_FW_FENCE_I_SENT,
[SBI_TLB_SFENCE_VMA] = SBI_PMU_FW_SFENCE_VMA_SENT,
[SBI_TLB_SFENCE_VMA_ASID] = SBI_PMU_FW_SFENCE_VMA_ASID_SENT,
[SBI_TLB_HFENCE_GVMA_VMID] = SBI_PMU_FW_HFENCE_GVMA_VMID_SENT,
[SBI_TLB_HFENCE_GVMA] = SBI_PMU_FW_HFENCE_GVMA_SENT,
[SBI_TLB_HFENCE_VVMA_ASID] = SBI_PMU_FW_HFENCE_VVMA_ASID_SENT,
[SBI_TLB_HFENCE_VVMA] = SBI_PMU_FW_HFENCE_VVMA_SENT,
};
int sbi_tlb_request(ulong hmask, ulong hbase, struct sbi_tlb_info *tinfo)
{
if (!tinfo->local_fn)
if (tinfo->type < 0 || tinfo->type >= SBI_TLB_TYPE_MAX)
return SBI_EINVAL;
/*
@@ -385,7 +406,7 @@ int sbi_tlb_request(ulong hmask, ulong hbase, struct sbi_tlb_info *tinfo)
tinfo->size = SBI_TLB_FLUSH_ALL;
}
tlb_pmu_incr_fw_ctr(tinfo);
sbi_pmu_ctr_incr_fw(tlb_type_to_pmu_fw_event[tinfo->type]);
return sbi_ipi_send_many(hmask, hbase, tlb_event, tinfo);
}