Skip to content

Commit

Permalink
sgi-gru: aSID (context management) bug fixes
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jack Steiner authored and Linus Torvalds committed Apr 3, 2009
1 parent bb04aa7 commit 8741941
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 4 deletions.
1 change: 1 addition & 0 deletions drivers/misc/sgi-gru/grufile.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ static void gru_init_chiplet(struct gru_state *gru, unsigned long paddr,
gru->gs_blade_id = bid;
gru->gs_cbr_map = (GRU_CBR_AU == 64) ? ~0 : (1UL << GRU_CBR_AU) - 1;
gru->gs_dsr_map = (1UL << GRU_DSR_AU) - 1;
gru->gs_asid_limit = MAX_ASID;
gru_tgh_flush_init(gru);
gru_dbg(grudev, "bid %d, nid %d, gid %d, vaddr %p (0x%lx)\n",
bid, nid, gru->gs_gid, gru->gs_gru_base_vaddr,
Expand Down
13 changes: 9 additions & 4 deletions drivers/misc/sgi-gru/grumain.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ static int gru_wrap_asid(struct gru_state *gru)
gru_dbg(grudev, "gid %d\n", gru->gs_gid);
STAT(asid_wrap);
gru->gs_asid_gen++;
gru_flush_all_tlb(gru);
return MIN_ASID;
}

Expand All @@ -93,6 +92,7 @@ static int gru_reset_asid_limit(struct gru_state *gru, int asid)
limit = MAX_ASID;
if (asid >= limit)
asid = gru_wrap_asid(gru);
gru_flush_all_tlb(gru);
gid = gru->gs_gid;
again:
for (i = 0; i < GRU_NUM_CCH; i++) {
Expand Down Expand Up @@ -131,12 +131,10 @@ static int gru_assign_asid(struct gru_state *gru)
{
int asid;

spin_lock(&gru->gs_asid_lock);
gru->gs_asid += ASID_INC;
asid = gru->gs_asid;
if (asid >= gru->gs_asid_limit)
asid = gru_reset_asid_limit(gru, asid);
spin_unlock(&gru->gs_asid_lock);

gru_dbg(grudev, "gid %d, asid 0x%x\n", gru->gs_gid, asid);
return asid;
Expand Down Expand Up @@ -227,14 +225,17 @@ static int gru_load_mm_tracker(struct gru_state *gru,
spin_lock(&gms->ms_asid_lock);
asid = asids->mt_asid;

if (asid == 0 || asids->mt_asid_gen != gru->gs_asid_gen) {
spin_lock(&gru->gs_asid_lock);
if (asid == 0 || (asids->mt_ctxbitmap == 0 && asids->mt_asid_gen !=
gru->gs_asid_gen)) {
asid = gru_assign_asid(gru);
asids->mt_asid = asid;
asids->mt_asid_gen = gru->gs_asid_gen;
STAT(asid_new);
} else {
STAT(asid_reuse);
}
spin_unlock(&gru->gs_asid_lock);

BUG_ON(asids->mt_ctxbitmap & ctxbitmap);
asids->mt_ctxbitmap |= ctxbitmap;
Expand All @@ -259,10 +260,12 @@ static void gru_unload_mm_tracker(struct gru_state *gru,
asids = &gms->ms_asids[gru->gs_gid];
ctxbitmap = (1 << gts->ts_ctxnum);
spin_lock(&gms->ms_asid_lock);
spin_lock(&gru->gs_asid_lock);
BUG_ON((asids->mt_ctxbitmap & ctxbitmap) != ctxbitmap);
asids->mt_ctxbitmap ^= ctxbitmap;
gru_dbg(grudev, "gid %d, gts %p, gms %p, ctxnum 0x%d, asidmap 0x%lx\n",
gru->gs_gid, gts, gms, gts->ts_ctxnum, gms->ms_asidmap[0]);
spin_unlock(&gru->gs_asid_lock);
spin_unlock(&gms->ms_asid_lock);
}

Expand Down Expand Up @@ -412,6 +415,7 @@ static void gru_free_gru_context(struct gru_thread_state *gts)
__clear_bit(gts->ts_ctxnum, &gru->gs_context_map);
gts->ts_ctxnum = NULLCTX;
gts->ts_gru = NULL;
gts->ts_blade = -1;
spin_unlock(&gru->gs_lock);

gts_drop(gts);
Expand Down Expand Up @@ -731,6 +735,7 @@ static struct gru_state *gru_assign_gru_context(struct gru_thread_state *gts)
}
reserve_gru_resources(gru, gts);
gts->ts_gru = gru;
gts->ts_blade = gru->gs_blade_id;
gts->ts_ctxnum =
find_first_zero_bit(&gru->gs_context_map, GRU_NUM_CCH);
BUG_ON(gts->ts_ctxnum == GRU_NUM_CCH);
Expand Down

0 comments on commit 8741941

Please sign in to comment.