Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
8496f2a4
Commit
8496f2a4
authored
Oct 28, 2005
by
Tony Luck
Browse files
Options
Browse Files
Download
Plain Diff
Pull fix-slow-tlb-purge into release branch
parents
2d8f6a52
c1902aae
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
29 additions
and
20 deletions
+29
-20
arch/ia64/mm/tlb.c
arch/ia64/mm/tlb.c
+9
-7
arch/ia64/sn/kernel/sn2/sn2_smp.c
arch/ia64/sn/kernel/sn2/sn2_smp.c
+19
-12
include/asm-ia64/machvec.h
include/asm-ia64/machvec.h
+1
-1
No files found.
arch/ia64/mm/tlb.c
View file @
8496f2a4
...
@@ -87,10 +87,15 @@ wrap_mmu_context (struct mm_struct *mm)
...
@@ -87,10 +87,15 @@ wrap_mmu_context (struct mm_struct *mm)
}
}
void
void
ia64_global_tlb_purge
(
unsigned
long
start
,
unsigned
long
end
,
unsigned
long
nbits
)
ia64_global_tlb_purge
(
struct
mm_struct
*
mm
,
unsigned
long
start
,
unsigned
long
end
,
unsigned
long
nbits
)
{
{
static
DEFINE_SPINLOCK
(
ptcg_lock
);
static
DEFINE_SPINLOCK
(
ptcg_lock
);
if
(
mm
!=
current
->
active_mm
)
{
flush_tlb_all
();
return
;
}
/* HW requires global serialization of ptc.ga. */
/* HW requires global serialization of ptc.ga. */
spin_lock
(
&
ptcg_lock
);
spin_lock
(
&
ptcg_lock
);
{
{
...
@@ -136,15 +141,12 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long
...
@@ -136,15 +141,12 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long
unsigned
long
size
=
end
-
start
;
unsigned
long
size
=
end
-
start
;
unsigned
long
nbits
;
unsigned
long
nbits
;
#ifndef CONFIG_SMP
if
(
mm
!=
current
->
active_mm
)
{
if
(
mm
!=
current
->
active_mm
)
{
/* this does happen, but perhaps it's not worth optimizing for? */
#ifdef CONFIG_SMP
flush_tlb_all
();
#else
mm
->
context
=
0
;
mm
->
context
=
0
;
#endif
return
;
return
;
}
}
#endif
nbits
=
ia64_fls
(
size
+
0xfff
);
nbits
=
ia64_fls
(
size
+
0xfff
);
while
(
unlikely
(((
1UL
<<
nbits
)
&
purge
.
mask
)
==
0
)
&&
(
nbits
<
purge
.
max_bits
))
while
(
unlikely
(((
1UL
<<
nbits
)
&
purge
.
mask
)
==
0
)
&&
(
nbits
<
purge
.
max_bits
))
...
@@ -154,7 +156,7 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long
...
@@ -154,7 +156,7 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long
start
&=
~
((
1UL
<<
nbits
)
-
1
);
start
&=
~
((
1UL
<<
nbits
)
-
1
);
# ifdef CONFIG_SMP
# ifdef CONFIG_SMP
platform_global_tlb_purge
(
start
,
end
,
nbits
);
platform_global_tlb_purge
(
mm
,
start
,
end
,
nbits
);
# else
# else
do
{
do
{
ia64_ptcl
(
start
,
(
nbits
<<
2
));
ia64_ptcl
(
start
,
(
nbits
<<
2
));
...
...
arch/ia64/sn/kernel/sn2/sn2_smp.c
View file @
8496f2a4
...
@@ -177,6 +177,7 @@ void sn_tlb_migrate_finish(struct mm_struct *mm)
...
@@ -177,6 +177,7 @@ void sn_tlb_migrate_finish(struct mm_struct *mm)
/**
/**
* sn2_global_tlb_purge - globally purge translation cache of virtual address range
* sn2_global_tlb_purge - globally purge translation cache of virtual address range
* @mm: mm_struct containing virtual address range
* @start: start of virtual address range
* @start: start of virtual address range
* @end: end of virtual address range
* @end: end of virtual address range
* @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
* @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
...
@@ -188,21 +189,22 @@ void sn_tlb_migrate_finish(struct mm_struct *mm)
...
@@ -188,21 +189,22 @@ void sn_tlb_migrate_finish(struct mm_struct *mm)
* - cpu_vm_mask is a bit mask that indicates which cpus have loaded the context.
* - cpu_vm_mask is a bit mask that indicates which cpus have loaded the context.
* - cpu_vm_mask is converted into a nodemask of the nodes containing the
* - cpu_vm_mask is converted into a nodemask of the nodes containing the
* cpus in cpu_vm_mask.
* cpus in cpu_vm_mask.
* - if only one bit is set in cpu_vm_mask & it is the current cpu,
* - if only one bit is set in cpu_vm_mask & it is the current cpu & the
* then only the local TLB needs to be flushed. This flushing can be done
* process is purging its own virtual address range, then only the
* using ptc.l. This is the common case & avoids the global spinlock.
* local TLB needs to be flushed. This flushing can be done using
* ptc.l. This is the common case & avoids the global spinlock.
* - if multiple cpus have loaded the context, then flushing has to be
* - if multiple cpus have loaded the context, then flushing has to be
* done with ptc.g/MMRs under protection of the global ptc_lock.
* done with ptc.g/MMRs under protection of the global ptc_lock.
*/
*/
void
void
sn2_global_tlb_purge
(
unsigned
long
start
,
unsigned
long
end
,
sn2_global_tlb_purge
(
struct
mm_struct
*
mm
,
unsigned
long
start
,
unsigned
long
nbits
)
unsigned
long
end
,
unsigned
long
nbits
)
{
{
int
i
,
opt
,
shub1
,
cnode
,
mynasid
,
cpu
,
lcpu
=
0
,
nasid
,
flushed
=
0
;
int
i
,
opt
,
shub1
,
cnode
,
mynasid
,
cpu
,
lcpu
=
0
,
nasid
,
flushed
=
0
;
int
mymm
=
(
mm
==
current
->
active_mm
);
volatile
unsigned
long
*
ptc0
,
*
ptc1
;
volatile
unsigned
long
*
ptc0
,
*
ptc1
;
unsigned
long
itc
,
itc2
,
flags
,
data0
=
0
,
data1
=
0
;
unsigned
long
itc
,
itc2
,
flags
,
data0
=
0
,
data1
=
0
,
rr_value
;
struct
mm_struct
*
mm
=
current
->
active_mm
;
short
nasids
[
MAX_NUMNODES
],
nix
;
short
nasids
[
MAX_NUMNODES
],
nix
;
nodemask_t
nodes_flushed
;
nodemask_t
nodes_flushed
;
...
@@ -216,9 +218,12 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
...
@@ -216,9 +218,12 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
i
++
;
i
++
;
}
}
if
(
i
==
0
)
return
;
preempt_disable
();
preempt_disable
();
if
(
likely
(
i
==
1
&&
lcpu
==
smp_processor_id
()))
{
if
(
likely
(
i
==
1
&&
lcpu
==
smp_processor_id
()
&&
mymm
))
{
do
{
do
{
ia64_ptcl
(
start
,
nbits
<<
2
);
ia64_ptcl
(
start
,
nbits
<<
2
);
start
+=
(
1UL
<<
nbits
);
start
+=
(
1UL
<<
nbits
);
...
@@ -229,7 +234,7 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
...
@@ -229,7 +234,7 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
return
;
return
;
}
}
if
(
atomic_read
(
&
mm
->
mm_users
)
==
1
)
{
if
(
atomic_read
(
&
mm
->
mm_users
)
==
1
&&
mymm
)
{
flush_tlb_mm
(
mm
);
flush_tlb_mm
(
mm
);
__get_cpu_var
(
ptcstats
).
change_rid
++
;
__get_cpu_var
(
ptcstats
).
change_rid
++
;
preempt_enable
();
preempt_enable
();
...
@@ -241,11 +246,13 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
...
@@ -241,11 +246,13 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
for_each_node_mask
(
cnode
,
nodes_flushed
)
for_each_node_mask
(
cnode
,
nodes_flushed
)
nasids
[
nix
++
]
=
cnodeid_to_nasid
(
cnode
);
nasids
[
nix
++
]
=
cnodeid_to_nasid
(
cnode
);
rr_value
=
(
mm
->
context
<<
3
)
|
REGION_NUMBER
(
start
);
shub1
=
is_shub1
();
shub1
=
is_shub1
();
if
(
shub1
)
{
if
(
shub1
)
{
data0
=
(
1UL
<<
SH1_PTC_0_A_SHFT
)
|
data0
=
(
1UL
<<
SH1_PTC_0_A_SHFT
)
|
(
nbits
<<
SH1_PTC_0_PS_SHFT
)
|
(
nbits
<<
SH1_PTC_0_PS_SHFT
)
|
((
ia64_get_rr
(
start
)
>>
8
)
<<
SH1_PTC_0_RID_SHFT
)
|
(
rr_value
<<
SH1_PTC_0_RID_SHFT
)
|
(
1UL
<<
SH1_PTC_0_START_SHFT
);
(
1UL
<<
SH1_PTC_0_START_SHFT
);
ptc0
=
(
long
*
)
GLOBAL_MMR_PHYS_ADDR
(
0
,
SH1_PTC_0
);
ptc0
=
(
long
*
)
GLOBAL_MMR_PHYS_ADDR
(
0
,
SH1_PTC_0
);
ptc1
=
(
long
*
)
GLOBAL_MMR_PHYS_ADDR
(
0
,
SH1_PTC_1
);
ptc1
=
(
long
*
)
GLOBAL_MMR_PHYS_ADDR
(
0
,
SH1_PTC_1
);
...
@@ -254,7 +261,7 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
...
@@ -254,7 +261,7 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
(
nbits
<<
SH2_PTC_PS_SHFT
)
|
(
nbits
<<
SH2_PTC_PS_SHFT
)
|
(
1UL
<<
SH2_PTC_START_SHFT
);
(
1UL
<<
SH2_PTC_START_SHFT
);
ptc0
=
(
long
*
)
GLOBAL_MMR_PHYS_ADDR
(
0
,
SH2_PTC
+
ptc0
=
(
long
*
)
GLOBAL_MMR_PHYS_ADDR
(
0
,
SH2_PTC
+
(
(
ia64_get_rr
(
start
)
>>
8
)
<<
SH2_PTC_RID_SHFT
)
);
(
rr_value
<<
SH2_PTC_RID_SHFT
)
);
ptc1
=
NULL
;
ptc1
=
NULL
;
}
}
...
@@ -275,7 +282,7 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
...
@@ -275,7 +282,7 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
data0
=
(
data0
&
~
SH2_PTC_ADDR_MASK
)
|
(
start
&
SH2_PTC_ADDR_MASK
);
data0
=
(
data0
&
~
SH2_PTC_ADDR_MASK
)
|
(
start
&
SH2_PTC_ADDR_MASK
);
for
(
i
=
0
;
i
<
nix
;
i
++
)
{
for
(
i
=
0
;
i
<
nix
;
i
++
)
{
nasid
=
nasids
[
i
];
nasid
=
nasids
[
i
];
if
((
!
(
sn2_ptctest
&
3
))
&&
unlikely
(
nasid
==
mynasid
))
{
if
((
!
(
sn2_ptctest
&
3
))
&&
unlikely
(
nasid
==
mynasid
&&
mymm
))
{
ia64_ptcga
(
start
,
nbits
<<
2
);
ia64_ptcga
(
start
,
nbits
<<
2
);
ia64_srlz_i
();
ia64_srlz_i
();
}
else
{
}
else
{
...
...
include/asm-ia64/machvec.h
View file @
8496f2a4
...
@@ -26,7 +26,7 @@ typedef void ia64_mv_cpu_init_t (void);
...
@@ -26,7 +26,7 @@ typedef void ia64_mv_cpu_init_t (void);
typedef
void
ia64_mv_irq_init_t
(
void
);
typedef
void
ia64_mv_irq_init_t
(
void
);
typedef
void
ia64_mv_send_ipi_t
(
int
,
int
,
int
,
int
);
typedef
void
ia64_mv_send_ipi_t
(
int
,
int
,
int
,
int
);
typedef
void
ia64_mv_timer_interrupt_t
(
int
,
void
*
,
struct
pt_regs
*
);
typedef
void
ia64_mv_timer_interrupt_t
(
int
,
void
*
,
struct
pt_regs
*
);
typedef
void
ia64_mv_global_tlb_purge_t
(
unsigned
long
,
unsigned
long
,
unsigned
long
);
typedef
void
ia64_mv_global_tlb_purge_t
(
struct
mm_struct
*
,
unsigned
long
,
unsigned
long
,
unsigned
long
);
typedef
void
ia64_mv_tlb_migrate_finish_t
(
struct
mm_struct
*
);
typedef
void
ia64_mv_tlb_migrate_finish_t
(
struct
mm_struct
*
);
typedef
unsigned
int
ia64_mv_local_vector_to_irq
(
u8
);
typedef
unsigned
int
ia64_mv_local_vector_to_irq
(
u8
);
typedef
char
*
ia64_mv_pci_get_legacy_mem_t
(
struct
pci_bus
*
);
typedef
char
*
ia64_mv_pci_get_legacy_mem_t
(
struct
pci_bus
*
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment