aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/sgi-gru/grumain.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/sgi-gru/grumain.c')
-rw-r--r--drivers/misc/sgi-gru/grumain.c60
1 files changed, 31 insertions, 29 deletions
diff --git a/drivers/misc/sgi-gru/grumain.c b/drivers/misc/sgi-gru/grumain.c
index 374af38862e6..14baabc79da4 100644
--- a/drivers/misc/sgi-gru/grumain.c
+++ b/drivers/misc/sgi-gru/grumain.c
@@ -299,15 +299,13 @@ static struct gru_thread_state *gru_find_current_gts_nolock(struct gru_vma_data
299/* 299/*
300 * Allocate a thread state structure. 300 * Allocate a thread state structure.
301 */ 301 */
302static struct gru_thread_state *gru_alloc_gts(struct vm_area_struct *vma, 302struct gru_thread_state *gru_alloc_gts(struct vm_area_struct *vma,
303 struct gru_vma_data *vdata, 303 int cbr_au_count, int dsr_au_count, int options, int tsid)
304 int tsid)
305{ 304{
306 struct gru_thread_state *gts; 305 struct gru_thread_state *gts;
307 int bytes; 306 int bytes;
308 307
309 bytes = DSR_BYTES(vdata->vd_dsr_au_count) + 308 bytes = DSR_BYTES(dsr_au_count) + CBR_BYTES(cbr_au_count);
310 CBR_BYTES(vdata->vd_cbr_au_count);
311 bytes += sizeof(struct gru_thread_state); 309 bytes += sizeof(struct gru_thread_state);
312 gts = kzalloc(bytes, GFP_KERNEL); 310 gts = kzalloc(bytes, GFP_KERNEL);
313 if (!gts) 311 if (!gts)
@@ -316,21 +314,22 @@ static struct gru_thread_state *gru_alloc_gts(struct vm_area_struct *vma,
316 STAT(gts_alloc); 314 STAT(gts_alloc);
317 atomic_set(&gts->ts_refcnt, 1); 315 atomic_set(&gts->ts_refcnt, 1);
318 mutex_init(&gts->ts_ctxlock); 316 mutex_init(&gts->ts_ctxlock);
319 gts->ts_cbr_au_count = vdata->vd_cbr_au_count; 317 gts->ts_cbr_au_count = cbr_au_count;
320 gts->ts_dsr_au_count = vdata->vd_dsr_au_count; 318 gts->ts_dsr_au_count = dsr_au_count;
321 gts->ts_user_options = vdata->vd_user_options; 319 gts->ts_user_options = options;
322 gts->ts_tsid = tsid; 320 gts->ts_tsid = tsid;
323 gts->ts_user_options = vdata->vd_user_options;
324 gts->ts_ctxnum = NULLCTX; 321 gts->ts_ctxnum = NULLCTX;
325 gts->ts_mm = current->mm;
326 gts->ts_vma = vma;
327 gts->ts_tlb_int_select = -1; 322 gts->ts_tlb_int_select = -1;
328 gts->ts_gms = gru_register_mmu_notifier();
329 gts->ts_sizeavail = GRU_SIZEAVAIL(PAGE_SHIFT); 323 gts->ts_sizeavail = GRU_SIZEAVAIL(PAGE_SHIFT);
330 if (!gts->ts_gms) 324 if (vma) {
331 goto err; 325 gts->ts_mm = current->mm;
326 gts->ts_vma = vma;
327 gts->ts_gms = gru_register_mmu_notifier();
328 if (!gts->ts_gms)
329 goto err;
330 }
332 331
333 gru_dbg(grudev, "alloc vdata %p, new gts %p\n", vdata, gts); 332 gru_dbg(grudev, "alloc gts %p\n", gts);
334 return gts; 333 return gts;
335 334
336err: 335err:
@@ -381,7 +380,8 @@ struct gru_thread_state *gru_alloc_thread_state(struct vm_area_struct *vma,
381 struct gru_vma_data *vdata = vma->vm_private_data; 380 struct gru_vma_data *vdata = vma->vm_private_data;
382 struct gru_thread_state *gts, *ngts; 381 struct gru_thread_state *gts, *ngts;
383 382
384 gts = gru_alloc_gts(vma, vdata, tsid); 383 gts = gru_alloc_gts(vma, vdata->vd_cbr_au_count, vdata->vd_dsr_au_count,
384 vdata->vd_user_options, tsid);
385 if (!gts) 385 if (!gts)
386 return NULL; 386 return NULL;
387 387
@@ -645,7 +645,7 @@ static int gru_retarget_intr(struct gru_thread_state *gts)
645#define next_gru(b, g) (((g) < &(b)->bs_grus[GRU_CHIPLETS_PER_BLADE - 1]) ? \ 645#define next_gru(b, g) (((g) < &(b)->bs_grus[GRU_CHIPLETS_PER_BLADE - 1]) ? \
646 ((g)+1) : &(b)->bs_grus[0]) 646 ((g)+1) : &(b)->bs_grus[0])
647 647
648static void gru_steal_context(struct gru_thread_state *gts) 648static void gru_steal_context(struct gru_thread_state *gts, int blade_id)
649{ 649{
650 struct gru_blade_state *blade; 650 struct gru_blade_state *blade;
651 struct gru_state *gru, *gru0; 651 struct gru_state *gru, *gru0;
@@ -655,8 +655,7 @@ static void gru_steal_context(struct gru_thread_state *gts)
655 cbr = gts->ts_cbr_au_count; 655 cbr = gts->ts_cbr_au_count;
656 dsr = gts->ts_dsr_au_count; 656 dsr = gts->ts_dsr_au_count;
657 657
658 preempt_disable(); 658 blade = gru_base[blade_id];
659 blade = gru_base[uv_numa_blade_id()];
660 spin_lock(&blade->bs_lock); 659 spin_lock(&blade->bs_lock);
661 660
662 ctxnum = next_ctxnum(blade->bs_lru_ctxnum); 661 ctxnum = next_ctxnum(blade->bs_lru_ctxnum);
@@ -693,7 +692,6 @@ static void gru_steal_context(struct gru_thread_state *gts)
693 blade->bs_lru_gru = gru; 692 blade->bs_lru_gru = gru;
694 blade->bs_lru_ctxnum = ctxnum; 693 blade->bs_lru_ctxnum = ctxnum;
695 spin_unlock(&blade->bs_lock); 694 spin_unlock(&blade->bs_lock);
696 preempt_enable();
697 695
698 if (ngts) { 696 if (ngts) {
699 STAT(steal_context); 697 STAT(steal_context);
@@ -713,17 +711,17 @@ static void gru_steal_context(struct gru_thread_state *gts)
713/* 711/*
714 * Scan the GRUs on the local blade & assign a GRU context. 712 * Scan the GRUs on the local blade & assign a GRU context.
715 */ 713 */
716static struct gru_state *gru_assign_gru_context(struct gru_thread_state *gts) 714static struct gru_state *gru_assign_gru_context(struct gru_thread_state *gts,
715 int blade)
717{ 716{
718 struct gru_state *gru, *grux; 717 struct gru_state *gru, *grux;
719 int i, max_active_contexts; 718 int i, max_active_contexts;
720 719
721 preempt_disable();
722 720
723again: 721again:
724 gru = NULL; 722 gru = NULL;
725 max_active_contexts = GRU_NUM_CCH; 723 max_active_contexts = GRU_NUM_CCH;
726 for_each_gru_on_blade(grux, uv_numa_blade_id(), i) { 724 for_each_gru_on_blade(grux, blade, i) {
727 if (check_gru_resources(grux, gts->ts_cbr_au_count, 725 if (check_gru_resources(grux, gts->ts_cbr_au_count,
728 gts->ts_dsr_au_count, 726 gts->ts_dsr_au_count,
729 max_active_contexts)) { 727 max_active_contexts)) {
@@ -763,7 +761,6 @@ again:
763 STAT(assign_context_failed); 761 STAT(assign_context_failed);
764 } 762 }
765 763
766 preempt_enable();
767 return gru; 764 return gru;
768} 765}
769 766
@@ -778,6 +775,7 @@ int gru_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
778{ 775{
779 struct gru_thread_state *gts; 776 struct gru_thread_state *gts;
780 unsigned long paddr, vaddr; 777 unsigned long paddr, vaddr;
778 int blade_id;
781 779
782 vaddr = (unsigned long)vmf->virtual_address; 780 vaddr = (unsigned long)vmf->virtual_address;
783 gru_dbg(grudev, "vma %p, vaddr 0x%lx (0x%lx)\n", 781 gru_dbg(grudev, "vma %p, vaddr 0x%lx (0x%lx)\n",
@@ -792,8 +790,10 @@ int gru_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
792again: 790again:
793 mutex_lock(&gts->ts_ctxlock); 791 mutex_lock(&gts->ts_ctxlock);
794 preempt_disable(); 792 preempt_disable();
793 blade_id = uv_numa_blade_id();
794
795 if (gts->ts_gru) { 795 if (gts->ts_gru) {
796 if (gts->ts_gru->gs_blade_id != uv_numa_blade_id()) { 796 if (gts->ts_gru->gs_blade_id != blade_id) {
797 STAT(migrated_nopfn_unload); 797 STAT(migrated_nopfn_unload);
798 gru_unload_context(gts, 1); 798 gru_unload_context(gts, 1);
799 } else { 799 } else {
@@ -803,12 +803,14 @@ again:
803 } 803 }
804 804
805 if (!gts->ts_gru) { 805 if (!gts->ts_gru) {
806 if (!gru_assign_gru_context(gts)) { 806 if (!gru_assign_gru_context(gts, blade_id)) {
807 mutex_unlock(&gts->ts_ctxlock);
808 preempt_enable(); 807 preempt_enable();
808 mutex_unlock(&gts->ts_ctxlock);
809 set_current_state(TASK_INTERRUPTIBLE);
809 schedule_timeout(GRU_ASSIGN_DELAY); /* true hack ZZZ */ 810 schedule_timeout(GRU_ASSIGN_DELAY); /* true hack ZZZ */
811 blade_id = uv_numa_blade_id();
810 if (gts->ts_steal_jiffies + GRU_STEAL_DELAY < jiffies) 812 if (gts->ts_steal_jiffies + GRU_STEAL_DELAY < jiffies)
811 gru_steal_context(gts); 813 gru_steal_context(gts, blade_id);
812 goto again; 814 goto again;
813 } 815 }
814 gru_load_context(gts); 816 gru_load_context(gts);
@@ -818,8 +820,8 @@ again:
818 vma->vm_page_prot); 820 vma->vm_page_prot);
819 } 821 }
820 822
821 mutex_unlock(&gts->ts_ctxlock);
822 preempt_enable(); 823 preempt_enable();
824 mutex_unlock(&gts->ts_ctxlock);
823 825
824 return VM_FAULT_NOPAGE; 826 return VM_FAULT_NOPAGE;
825} 827}