aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/sgi-gru/grumain.c
diff options
context:
space:
mode:
authorJack Steiner <steiner@sgi.com>2009-04-02 19:59:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-02 22:05:06 -0400
commit874194123718e625aa96632bac457d686ba1378e (patch)
tree0594c7d50d05157f564afdd364956daa4062cf9f /drivers/misc/sgi-gru/grumain.c
parentbb04aa78ec1393295c30edad154e6f6e906955f3 (diff)
sgi-gru: aSID (context management) bug fixes
This patch fixes bugs related to ASID (context id) management in the GRU driver. These changes are all internal to the SGI GRU driver and have no effect on the base kernel. Signed-off-by: Jack Steiner <steiner@sgi.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/misc/sgi-gru/grumain.c')
-rw-r--r--drivers/misc/sgi-gru/grumain.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/misc/sgi-gru/grumain.c b/drivers/misc/sgi-gru/grumain.c
index de60458f6d1e..5fc7b5ecde66 100644
--- a/drivers/misc/sgi-gru/grumain.c
+++ b/drivers/misc/sgi-gru/grumain.c
@@ -79,7 +79,6 @@ static int gru_wrap_asid(struct gru_state *gru)
79 gru_dbg(grudev, "gid %d\n", gru->gs_gid); 79 gru_dbg(grudev, "gid %d\n", gru->gs_gid);
80 STAT(asid_wrap); 80 STAT(asid_wrap);
81 gru->gs_asid_gen++; 81 gru->gs_asid_gen++;
82 gru_flush_all_tlb(gru);
83 return MIN_ASID; 82 return MIN_ASID;
84} 83}
85 84
@@ -93,6 +92,7 @@ static int gru_reset_asid_limit(struct gru_state *gru, int asid)
93 limit = MAX_ASID; 92 limit = MAX_ASID;
94 if (asid >= limit) 93 if (asid >= limit)
95 asid = gru_wrap_asid(gru); 94 asid = gru_wrap_asid(gru);
95 gru_flush_all_tlb(gru);
96 gid = gru->gs_gid; 96 gid = gru->gs_gid;
97again: 97again:
98 for (i = 0; i < GRU_NUM_CCH; i++) { 98 for (i = 0; i < GRU_NUM_CCH; i++) {
@@ -131,12 +131,10 @@ static int gru_assign_asid(struct gru_state *gru)
131{ 131{
132 int asid; 132 int asid;
133 133
134 spin_lock(&gru->gs_asid_lock);
135 gru->gs_asid += ASID_INC; 134 gru->gs_asid += ASID_INC;
136 asid = gru->gs_asid; 135 asid = gru->gs_asid;
137 if (asid >= gru->gs_asid_limit) 136 if (asid >= gru->gs_asid_limit)
138 asid = gru_reset_asid_limit(gru, asid); 137 asid = gru_reset_asid_limit(gru, asid);
139 spin_unlock(&gru->gs_asid_lock);
140 138
141 gru_dbg(grudev, "gid %d, asid 0x%x\n", gru->gs_gid, asid); 139 gru_dbg(grudev, "gid %d, asid 0x%x\n", gru->gs_gid, asid);
142 return asid; 140 return asid;
@@ -227,7 +225,9 @@ static int gru_load_mm_tracker(struct gru_state *gru,
227 spin_lock(&gms->ms_asid_lock); 225 spin_lock(&gms->ms_asid_lock);
228 asid = asids->mt_asid; 226 asid = asids->mt_asid;
229 227
230 if (asid == 0 || asids->mt_asid_gen != gru->gs_asid_gen) { 228 spin_lock(&gru->gs_asid_lock);
229 if (asid == 0 || (asids->mt_ctxbitmap == 0 && asids->mt_asid_gen !=
230 gru->gs_asid_gen)) {
231 asid = gru_assign_asid(gru); 231 asid = gru_assign_asid(gru);
232 asids->mt_asid = asid; 232 asids->mt_asid = asid;
233 asids->mt_asid_gen = gru->gs_asid_gen; 233 asids->mt_asid_gen = gru->gs_asid_gen;
@@ -235,6 +235,7 @@ static int gru_load_mm_tracker(struct gru_state *gru,
235 } else { 235 } else {
236 STAT(asid_reuse); 236 STAT(asid_reuse);
237 } 237 }
238 spin_unlock(&gru->gs_asid_lock);
238 239
239 BUG_ON(asids->mt_ctxbitmap & ctxbitmap); 240 BUG_ON(asids->mt_ctxbitmap & ctxbitmap);
240 asids->mt_ctxbitmap |= ctxbitmap; 241 asids->mt_ctxbitmap |= ctxbitmap;
@@ -259,10 +260,12 @@ static void gru_unload_mm_tracker(struct gru_state *gru,
259 asids = &gms->ms_asids[gru->gs_gid]; 260 asids = &gms->ms_asids[gru->gs_gid];
260 ctxbitmap = (1 << gts->ts_ctxnum); 261 ctxbitmap = (1 << gts->ts_ctxnum);
261 spin_lock(&gms->ms_asid_lock); 262 spin_lock(&gms->ms_asid_lock);
263 spin_lock(&gru->gs_asid_lock);
262 BUG_ON((asids->mt_ctxbitmap & ctxbitmap) != ctxbitmap); 264 BUG_ON((asids->mt_ctxbitmap & ctxbitmap) != ctxbitmap);
263 asids->mt_ctxbitmap ^= ctxbitmap; 265 asids->mt_ctxbitmap ^= ctxbitmap;
264 gru_dbg(grudev, "gid %d, gts %p, gms %p, ctxnum 0x%d, asidmap 0x%lx\n", 266 gru_dbg(grudev, "gid %d, gts %p, gms %p, ctxnum 0x%d, asidmap 0x%lx\n",
265 gru->gs_gid, gts, gms, gts->ts_ctxnum, gms->ms_asidmap[0]); 267 gru->gs_gid, gts, gms, gts->ts_ctxnum, gms->ms_asidmap[0]);
268 spin_unlock(&gru->gs_asid_lock);
266 spin_unlock(&gms->ms_asid_lock); 269 spin_unlock(&gms->ms_asid_lock);
267} 270}
268 271
@@ -412,6 +415,7 @@ static void gru_free_gru_context(struct gru_thread_state *gts)
412 __clear_bit(gts->ts_ctxnum, &gru->gs_context_map); 415 __clear_bit(gts->ts_ctxnum, &gru->gs_context_map);
413 gts->ts_ctxnum = NULLCTX; 416 gts->ts_ctxnum = NULLCTX;
414 gts->ts_gru = NULL; 417 gts->ts_gru = NULL;
418 gts->ts_blade = -1;
415 spin_unlock(&gru->gs_lock); 419 spin_unlock(&gru->gs_lock);
416 420
417 gts_drop(gts); 421 gts_drop(gts);
@@ -731,6 +735,7 @@ again:
731 } 735 }
732 reserve_gru_resources(gru, gts); 736 reserve_gru_resources(gru, gts);
733 gts->ts_gru = gru; 737 gts->ts_gru = gru;
738 gts->ts_blade = gru->gs_blade_id;
734 gts->ts_ctxnum = 739 gts->ts_ctxnum =
735 find_first_zero_bit(&gru->gs_context_map, GRU_NUM_CCH); 740 find_first_zero_bit(&gru->gs_context_map, GRU_NUM_CCH);
736 BUG_ON(gts->ts_ctxnum == GRU_NUM_CCH); 741 BUG_ON(gts->ts_ctxnum == GRU_NUM_CCH);