source: mainline/genarch/src/mm/asid.c@ 02f441c0

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 02f441c0 was 7e4e532, checked in by Jakub Jermar <jakub@…>, 20 years ago

Reimplement ASID stealing logic.
This time, hopefully, with correct synchronization.

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/*
2 * Copyright (C) 2006 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/*
30 * ASID management.
31 *
32 * Modern processor architectures optimize TLB utilization
33 * by using ASIDs (a.k.a. memory contexts on sparc64 and
34 * region identifiers on ia64). These ASIDs help to associate
35 * each TLB item with an address space, thus making
36 * finer-grained TLB invalidation possible.
37 *
38 * Unfortunatelly, there are usually less ASIDs available than
39 * there can be unique as_t structures (i.e. address spaces
40 * recognized by the kernel).
41 *
42 * When system runs short of ASIDs, it will attempt to steal
43 * ASID from an address space that has not been active for
44 * a while.
45 *
46 * This code depends on the fact that ASIDS_ALLOCABLE
47 * is greater than number of supported CPUs (i.e. the
48 * amount of concurently active address spaces).
49 *
50 * Architectures that don't have hardware support for address
51 * spaces do not compile with this file.
52 */
53
54#include <mm/asid.h>
55#include <mm/as.h>
56#include <mm/tlb.h>
57#include <arch/mm/asid.h>
58#include <synch/spinlock.h>
59#include <arch.h>
60#include <adt/list.h>
61#include <debug.h>
62
63/**
64 * asidlock protects the asids_allocated counter.
65 */
66SPINLOCK_INITIALIZE(asidlock);
67
68static count_t asids_allocated = 0;
69
70/** Allocate free address space identifier.
71 *
72 * Interrupts must be disabled and as_lock must be held
73 * prior to this call
74 *
75 * @return New ASID.
76 */
77asid_t asid_get(void)
78{
79 asid_t asid;
80 link_t *tmp;
81 as_t *as;
82
83 /*
84 * Check if there is an unallocated ASID.
85 */
86
87 spinlock_lock(&asidlock);
88 if (asids_allocated == ASIDS_ALLOCABLE) {
89
90 /*
91 * All ASIDs are already allocated.
92 * Resort to stealing.
93 */
94
95 /*
96 * Remove the first item on the list.
97 * It is guaranteed to belong to an
98 * inactive address space.
99 */
100 ASSERT(!list_empty(&inactive_as_with_asid_head));
101 tmp = inactive_as_with_asid_head.next;
102 list_remove(tmp);
103
104 as = list_get_instance(tmp, as_t, inactive_as_with_asid_link);
105 spinlock_lock(&as->lock);
106
107 /*
108 * Steal the ASID.
109 * Note that the stolen ASID is not active.
110 */
111 asid = as->asid;
112 ASSERT(asid != ASID_INVALID);
113
114 /*
115 * Notify the address space from wich the ASID
116 * was stolen by invalidating its asid member.
117 */
118 as->asid = ASID_INVALID;
119 spinlock_unlock(&as->lock);
120
121 /*
122 * Get the system rid of the stolen ASID.
123 */
124 tlb_shootdown_start(TLB_INVL_ASID, asid, 0, 0);
125 tlb_shootdown_finalize();
126 tlb_invalidate_asid(asid);
127 } else {
128
129 /*
130 * There is at least one unallocated ASID.
131 * Find it and assign it.
132 */
133
134 asid = asid_find_free();
135 asids_allocated++;
136 }
137
138 spinlock_unlock(&asidlock);
139
140 return asid;
141}
142
143/** Release address space identifier.
144 *
145 * This code relies on architecture
146 * dependent functionality.
147 *
148 * @param asid ASID to be released.
149 */
150void asid_put(asid_t asid)
151{
152 ipl_t ipl;
153
154 ipl = interrupts_disable();
155 spinlock_lock(&asidlock);
156
157 asids_allocated--;
158 asid_put_arch(asid);
159
160 spinlock_unlock(&asidlock);
161 interrupts_restore(ipl);
162}
Note: See TracBrowser for help on using the repository browser.