diff options
Diffstat (limited to 'drivers/misc/sgi-gru/grumain.c')
-rw-r--r-- | drivers/misc/sgi-gru/grumain.c | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/drivers/misc/sgi-gru/grumain.c b/drivers/misc/sgi-gru/grumain.c index 0c7bd384f0cf..3398e54a762b 100644 --- a/drivers/misc/sgi-gru/grumain.c +++ b/drivers/misc/sgi-gru/grumain.c | |||
@@ -96,7 +96,7 @@ static int gru_reset_asid_limit(struct gru_state *gru, int asid) | |||
96 | gid = gru->gs_gid; | 96 | gid = gru->gs_gid; |
97 | again: | 97 | again: |
98 | for (i = 0; i < GRU_NUM_CCH; i++) { | 98 | for (i = 0; i < GRU_NUM_CCH; i++) { |
99 | if (!gru->gs_gts[i]) | 99 | if (!gru->gs_gts[i] || is_kernel_context(gru->gs_gts[i])) |
100 | continue; | 100 | continue; |
101 | inuse_asid = gru->gs_gts[i]->ts_gms->ms_asids[gid].mt_asid; | 101 | inuse_asid = gru->gs_gts[i]->ts_gms->ms_asids[gid].mt_asid; |
102 | gru_dbg(grudev, "gid %d, gts %p, gms %p, inuse 0x%x, cxt %d\n", | 102 | gru_dbg(grudev, "gid %d, gts %p, gms %p, inuse 0x%x, cxt %d\n", |
@@ -506,7 +506,8 @@ void gru_unload_context(struct gru_thread_state *gts, int savestate) | |||
506 | struct gru_context_configuration_handle *cch; | 506 | struct gru_context_configuration_handle *cch; |
507 | int ctxnum = gts->ts_ctxnum; | 507 | int ctxnum = gts->ts_ctxnum; |
508 | 508 | ||
509 | zap_vma_ptes(gts->ts_vma, UGRUADDR(gts), GRU_GSEG_PAGESIZE); | 509 | if (!is_kernel_context(gts)) |
510 | zap_vma_ptes(gts->ts_vma, UGRUADDR(gts), GRU_GSEG_PAGESIZE); | ||
510 | cch = get_cch(gru->gs_gru_base_vaddr, ctxnum); | 511 | cch = get_cch(gru->gs_gru_base_vaddr, ctxnum); |
511 | 512 | ||
512 | gru_dbg(grudev, "gts %p\n", gts); | 513 | gru_dbg(grudev, "gts %p\n", gts); |
@@ -514,7 +515,8 @@ void gru_unload_context(struct gru_thread_state *gts, int savestate) | |||
514 | if (cch_interrupt_sync(cch)) | 515 | if (cch_interrupt_sync(cch)) |
515 | BUG(); | 516 | BUG(); |
516 | 517 | ||
517 | gru_unload_mm_tracker(gru, gts); | 518 | if (!is_kernel_context(gts)) |
519 | gru_unload_mm_tracker(gru, gts); | ||
518 | if (savestate) | 520 | if (savestate) |
519 | gru_unload_context_data(gts->ts_gdata, gru->gs_gru_base_vaddr, | 521 | gru_unload_context_data(gts->ts_gdata, gru->gs_gru_base_vaddr, |
520 | ctxnum, gts->ts_cbr_map, | 522 | ctxnum, gts->ts_cbr_map, |
@@ -526,7 +528,6 @@ void gru_unload_context(struct gru_thread_state *gts, int savestate) | |||
526 | unlock_cch_handle(cch); | 528 | unlock_cch_handle(cch); |
527 | 529 | ||
528 | gru_free_gru_context(gts); | 530 | gru_free_gru_context(gts); |
529 | STAT(unload_context); | ||
530 | } | 531 | } |
531 | 532 | ||
532 | /* | 533 | /* |
@@ -554,11 +555,16 @@ void gru_load_context(struct gru_thread_state *gts) | |||
554 | cch->tfm_done_bit_enable = 0; | 555 | cch->tfm_done_bit_enable = 0; |
555 | cch->dsr_allocation_map = gts->ts_dsr_map; | 556 | cch->dsr_allocation_map = gts->ts_dsr_map; |
556 | cch->cbr_allocation_map = gts->ts_cbr_map; | 557 | cch->cbr_allocation_map = gts->ts_cbr_map; |
557 | asid = gru_load_mm_tracker(gru, gts); | 558 | |
558 | cch->unmap_enable = 0; | 559 | if (is_kernel_context(gts)) { |
559 | for (i = 0; i < 8; i++) { | 560 | cch->unmap_enable = 1; |
560 | cch->asid[i] = asid + i; | 561 | } else { |
561 | cch->sizeavail[i] = gts->ts_sizeavail; | 562 | cch->unmap_enable = 0; |
563 | asid = gru_load_mm_tracker(gru, gts); | ||
564 | for (i = 0; i < 8; i++) { | ||
565 | cch->asid[i] = asid + i; | ||
566 | cch->sizeavail[i] = gts->ts_sizeavail; | ||
567 | } | ||
562 | } | 568 | } |
563 | 569 | ||
564 | err = cch_allocate(cch); | 570 | err = cch_allocate(cch); |
@@ -575,8 +581,6 @@ void gru_load_context(struct gru_thread_state *gts) | |||
575 | if (cch_start(cch)) | 581 | if (cch_start(cch)) |
576 | BUG(); | 582 | BUG(); |
577 | unlock_cch_handle(cch); | 583 | unlock_cch_handle(cch); |
578 | |||
579 | STAT(load_context); | ||
580 | } | 584 | } |
581 | 585 | ||
582 | /* | 586 | /* |
@@ -652,6 +656,27 @@ static int gru_retarget_intr(struct gru_thread_state *gts) | |||
652 | #define next_gru(b, g) (((g) < &(b)->bs_grus[GRU_CHIPLETS_PER_BLADE - 1]) ? \ | 656 | #define next_gru(b, g) (((g) < &(b)->bs_grus[GRU_CHIPLETS_PER_BLADE - 1]) ? \ |
653 | ((g)+1) : &(b)->bs_grus[0]) | 657 | ((g)+1) : &(b)->bs_grus[0]) |
654 | 658 | ||
659 | static int is_gts_stealable(struct gru_thread_state *gts, | ||
660 | struct gru_blade_state *bs) | ||
661 | { | ||
662 | if (is_kernel_context(gts)) | ||
663 | return down_write_trylock(&bs->bs_kgts_sema); | ||
664 | else | ||
665 | return mutex_trylock(>s->ts_ctxlock); | ||
666 | } | ||
667 | |||
668 | static void gts_stolen(struct gru_thread_state *gts, | ||
669 | struct gru_blade_state *bs) | ||
670 | { | ||
671 | if (is_kernel_context(gts)) { | ||
672 | up_write(&bs->bs_kgts_sema); | ||
673 | STAT(steal_kernel_context); | ||
674 | } else { | ||
675 | mutex_unlock(>s->ts_ctxlock); | ||
676 | STAT(steal_user_context); | ||
677 | } | ||
678 | } | ||
679 | |||
655 | void gru_steal_context(struct gru_thread_state *gts, int blade_id) | 680 | void gru_steal_context(struct gru_thread_state *gts, int blade_id) |
656 | { | 681 | { |
657 | struct gru_blade_state *blade; | 682 | struct gru_blade_state *blade; |
@@ -685,7 +710,7 @@ void gru_steal_context(struct gru_thread_state *gts, int blade_id) | |||
685 | * success are high. If trylock fails, try to steal a | 710 | * success are high. If trylock fails, try to steal a |
686 | * different GSEG. | 711 | * different GSEG. |
687 | */ | 712 | */ |
688 | if (ngts && mutex_trylock(&ngts->ts_ctxlock)) | 713 | if (ngts && is_gts_stealable(ngts, blade)) |
689 | break; | 714 | break; |
690 | ngts = NULL; | 715 | ngts = NULL; |
691 | flag = 1; | 716 | flag = 1; |
@@ -701,10 +726,9 @@ void gru_steal_context(struct gru_thread_state *gts, int blade_id) | |||
701 | spin_unlock(&blade->bs_lock); | 726 | spin_unlock(&blade->bs_lock); |
702 | 727 | ||
703 | if (ngts) { | 728 | if (ngts) { |
704 | STAT(steal_context); | ||
705 | ngts->ts_steal_jiffies = jiffies; | 729 | ngts->ts_steal_jiffies = jiffies; |
706 | gru_unload_context(ngts, 1); | 730 | gru_unload_context(ngts, is_kernel_context(ngts) ? 0 : 1); |
707 | mutex_unlock(&ngts->ts_ctxlock); | 731 | gts_stolen(ngts, blade); |
708 | } else { | 732 | } else { |
709 | STAT(steal_context_failed); | 733 | STAT(steal_context_failed); |
710 | } | 734 | } |
@@ -810,6 +834,7 @@ again: | |||
810 | } | 834 | } |
811 | 835 | ||
812 | if (!gts->ts_gru) { | 836 | if (!gts->ts_gru) { |
837 | STAT(load_user_context); | ||
813 | if (!gru_assign_gru_context(gts, blade_id)) { | 838 | if (!gru_assign_gru_context(gts, blade_id)) { |
814 | preempt_enable(); | 839 | preempt_enable(); |
815 | mutex_unlock(>s->ts_ctxlock); | 840 | mutex_unlock(>s->ts_ctxlock); |