Skip to content

Commit 7011018

Browse files
kvaneeshmpe
authored andcommitted
powerpc/mm: Reduce memory usage for mm_context_t for radix
Currently, our mm_context_t on book3s64 include all hash specific context details like slice mask and subpage protection details. We can skip allocating these with radix translation. This will help us to save 8K per mm_context with radix translation. With the patch applied we have sizeof(mm_context_t) = 136 sizeof(struct hash_mm_context) = 8288 Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
1 parent 67fda38 commit 7011018

File tree

5 files changed

+68
-40
lines changed

5 files changed

+68
-40
lines changed

arch/powerpc/include/asm/book3s/64/mmu-hash.h

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ extern void slb_set_size(u16 size);
658658
/* 4 bits per slice and we have one slice per 1TB */
659659
#define SLICE_ARRAY_SIZE (H_PGTABLE_RANGE >> 41)
660660
#define LOW_SLICE_ARRAY_SZ (BITS_PER_LONG / BITS_PER_BYTE)
661-
#define TASK_SLICE_ARRAY_SZ(x) ((x)->slb_addr_limit >> 41)
661+
#define TASK_SLICE_ARRAY_SZ(x) ((x)->hash_context->slb_addr_limit >> 41)
662662
#ifndef __ASSEMBLY__
663663

664664
#ifdef CONFIG_PPC_SUBPAGE_PROT
@@ -693,6 +693,37 @@ static inline void subpage_prot_free(struct mm_struct *mm) {}
693693
static inline void subpage_prot_init_new_context(struct mm_struct *mm) { }
694694
#endif /* CONFIG_PPC_SUBPAGE_PROT */
695695

696+
/*
697+
* One bit per slice. We have lower slices which cover 256MB segments
698+
* upto 4G range. That gets us 16 low slices. For the rest we track slices
699+
* in 1TB size.
700+
*/
701+
struct slice_mask {
702+
u64 low_slices;
703+
DECLARE_BITMAP(high_slices, SLICE_NUM_HIGH);
704+
};
705+
706+
struct hash_mm_context {
707+
u16 user_psize; /* page size index */
708+
709+
/* SLB page size encodings*/
710+
unsigned char low_slices_psize[LOW_SLICE_ARRAY_SZ];
711+
unsigned char high_slices_psize[SLICE_ARRAY_SIZE];
712+
unsigned long slb_addr_limit;
713+
#ifdef CONFIG_PPC_64K_PAGES
714+
struct slice_mask mask_64k;
715+
#endif
716+
struct slice_mask mask_4k;
717+
#ifdef CONFIG_HUGETLB_PAGE
718+
struct slice_mask mask_16m;
719+
struct slice_mask mask_16g;
720+
#endif
721+
722+
#ifdef CONFIG_PPC_SUBPAGE_PROT
723+
struct subpage_prot_table spt;
724+
#endif /* CONFIG_PPC_SUBPAGE_PROT */
725+
};
726+
696727
#if 0
697728
/*
698729
* The code below is equivalent to this function for arguments

arch/powerpc/include/asm/book3s/64/mmu.h

Lines changed: 12 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -104,16 +104,6 @@ struct spinlock;
104104
/* Maximum possible number of NPUs in a system. */
105105
#define NV_MAX_NPUS 8
106106

107-
/*
108-
* One bit per slice. We have lower slices which cover 256MB segments
109-
* upto 4G range. That gets us 16 low slices. For the rest we track slices
110-
* in 1TB size.
111-
*/
112-
struct slice_mask {
113-
u64 low_slices;
114-
DECLARE_BITMAP(high_slices, SLICE_NUM_HIGH);
115-
};
116-
117107
typedef struct {
118108
union {
119109
/*
@@ -127,7 +117,6 @@ typedef struct {
127117
mm_context_id_t id;
128118
mm_context_id_t extended_id[TASK_SIZE_USER64/TASK_CONTEXT_SIZE];
129119
};
130-
u16 user_psize; /* page size index */
131120

132121
/* Number of bits in the mm_cpumask */
133122
atomic_t active_cpus;
@@ -137,23 +126,9 @@ typedef struct {
137126

138127
/* NPU NMMU context */
139128
struct npu_context *npu_context;
129+
struct hash_mm_context *hash_context;
140130

141-
/* SLB page size encodings*/
142-
unsigned char low_slices_psize[LOW_SLICE_ARRAY_SZ];
143-
unsigned char high_slices_psize[SLICE_ARRAY_SIZE];
144-
unsigned long slb_addr_limit;
145-
# ifdef CONFIG_PPC_64K_PAGES
146-
struct slice_mask mask_64k;
147-
# endif
148-
struct slice_mask mask_4k;
149-
# ifdef CONFIG_HUGETLB_PAGE
150-
struct slice_mask mask_16m;
151-
struct slice_mask mask_16g;
152-
# endif
153131
unsigned long vdso_base;
154-
#ifdef CONFIG_PPC_SUBPAGE_PROT
155-
struct subpage_prot_table spt;
156-
#endif /* CONFIG_PPC_SUBPAGE_PROT */
157132
/*
158133
* pagetable fragment support
159134
*/
@@ -176,62 +151,62 @@ typedef struct {
176151

177152
static inline u16 mm_ctx_user_psize(mm_context_t *ctx)
178153
{
179-
return ctx->user_psize;
154+
return ctx->hash_context->user_psize;
180155
}
181156

182157
static inline void mm_ctx_set_user_psize(mm_context_t *ctx, u16 user_psize)
183158
{
184-
ctx->user_psize = user_psize;
159+
ctx->hash_context->user_psize = user_psize;
185160
}
186161

187162
static inline unsigned char *mm_ctx_low_slices(mm_context_t *ctx)
188163
{
189-
return ctx->low_slices_psize;
164+
return ctx->hash_context->low_slices_psize;
190165
}
191166

192167
static inline unsigned char *mm_ctx_high_slices(mm_context_t *ctx)
193168
{
194-
return ctx->high_slices_psize;
169+
return ctx->hash_context->high_slices_psize;
195170
}
196171

197172
static inline unsigned long mm_ctx_slb_addr_limit(mm_context_t *ctx)
198173
{
199-
return ctx->slb_addr_limit;
174+
return ctx->hash_context->slb_addr_limit;
200175
}
201176

202177
static inline void mm_ctx_set_slb_addr_limit(mm_context_t *ctx, unsigned long limit)
203178
{
204-
ctx->slb_addr_limit = limit;
179+
ctx->hash_context->slb_addr_limit = limit;
205180
}
206181

207182
#ifdef CONFIG_PPC_64K_PAGES
208183
static inline struct slice_mask *mm_ctx_slice_mask_64k(mm_context_t *ctx)
209184
{
210-
return &ctx->mask_64k;
185+
return &ctx->hash_context->mask_64k;
211186
}
212187
#endif
213188

214189
static inline struct slice_mask *mm_ctx_slice_mask_4k(mm_context_t *ctx)
215190
{
216-
return &ctx->mask_4k;
191+
return &ctx->hash_context->mask_4k;
217192
}
218193

219194
#ifdef CONFIG_HUGETLB_PAGE
220195
static inline struct slice_mask *mm_ctx_slice_mask_16m(mm_context_t *ctx)
221196
{
222-
return &ctx->mask_16m;
197+
return &ctx->hash_context->mask_16m;
223198
}
224199

225200
static inline struct slice_mask *mm_ctx_slice_mask_16g(mm_context_t *ctx)
226201
{
227-
return &ctx->mask_16g;
202+
return &ctx->hash_context->mask_16g;
228203
}
229204
#endif
230205

231206
#ifdef CONFIG_PPC_SUBPAGE_PROT
232207
static inline struct subpage_prot_table *mm_ctx_subpage_prot(mm_context_t *ctx)
233208
{
234-
return &ctx->spt;
209+
return &ctx->hash_context->spt;
235210
}
236211
#endif
237212

arch/powerpc/kernel/setup-common.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,12 @@ void __init setup_arch(char **cmdline_p)
947947
init_mm.end_data = (unsigned long) _edata;
948948
init_mm.brk = klimit;
949949

950+
#ifdef CONFIG_PPC_MM_SLICES
951+
#if defined(CONFIG_PPC_8xx)
952+
init_mm.context.slb_addr_limit = DEFAULT_MAP_WINDOW;
953+
#endif
954+
#endif
955+
950956
#ifdef CONFIG_SPAPR_TCE_IOMMU
951957
mm_iommu_init(&init_mm);
952958
#endif

arch/powerpc/mm/hash_utils_64.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,7 @@ void __init hash__early_init_devtree(void)
963963
htab_scan_page_sizes();
964964
}
965965

966+
struct hash_mm_context init_hash_mm_context;
966967
void __init hash__early_init_mmu(void)
967968
{
968969
#ifndef CONFIG_PPC_64K_PAGES
@@ -1036,7 +1037,8 @@ void __init hash__early_init_mmu(void)
10361037
*/
10371038
htab_initialize();
10381039

1039-
init_mm.context.slb_addr_limit = DEFAULT_MAP_WINDOW_USER64;
1040+
init_mm.context.hash_context = &init_hash_mm_context;
1041+
init_mm.context.hash_context->slb_addr_limit = DEFAULT_MAP_WINDOW_USER64;
10401042

10411043
pr_info("Initializing hash mmu with SLB\n");
10421044
/* Initialize SLB management */

arch/powerpc/mm/mmu_context_book3s64.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ static int hash__init_new_context(struct mm_struct *mm)
6363
if (index < 0)
6464
return index;
6565

66+
mm->context.hash_context = kmalloc(sizeof(struct hash_mm_context), GFP_KERNEL);
67+
if (!mm->context.hash_context) {
68+
ida_free(&mmu_context_ida, index);
69+
return -ENOMEM;
70+
}
71+
6672
/*
6773
* The old code would re-promote on fork, we don't do that when using
6874
* slices as it could cause problem promoting slices that have been
@@ -77,8 +83,14 @@ static int hash__init_new_context(struct mm_struct *mm)
7783
* We should not be calling init_new_context() on init_mm. Hence a
7884
* check against 0 is OK.
7985
*/
80-
if (mm->context.id == 0)
86+
if (mm->context.id == 0) {
87+
memset(mm->context.hash_context, 0, sizeof(struct hash_mm_context));
8188
slice_init_new_context_exec(mm);
89+
} else {
90+
/* This is fork. Copy hash_context details from current->mm */
91+
memcpy(mm->context.hash_context, current->mm->context.hash_context, sizeof(struct hash_mm_context));
92+
93+
}
8294

8395
subpage_prot_init_new_context(mm);
8496

@@ -118,6 +130,7 @@ static int radix__init_new_context(struct mm_struct *mm)
118130
asm volatile("ptesync;isync" : : : "memory");
119131

120132
mm->context.npu_context = NULL;
133+
mm->context.hash_context = NULL;
121134

122135
return index;
123136
}
@@ -162,6 +175,7 @@ static void destroy_contexts(mm_context_t *ctx)
162175
if (context_id)
163176
ida_free(&mmu_context_ida, context_id);
164177
}
178+
kfree(ctx->hash_context);
165179
}
166180

167181
static void pmd_frag_destroy(void *pmd_frag)

0 commit comments

Comments
 (0)