23 #include <linux/kernel.h>
24 #include <linux/slab.h>
27 #include <linux/sched.h>
28 #include <linux/device.h>
29 #include <linux/list.h>
31 #include <linux/prefetch.h>
32 #include <asm/uv/uv_hub.h>
43 static struct device gru_device = {
45 .driver = &gru_driver,
97 static int gru_wrap_asid(
struct gru_state *gru)
106 static int gru_reset_asid_limit(
struct gru_state *gru,
int asid)
114 asid = gru_wrap_asid(gru);
119 if (!gru->
gs_gts[i] || is_kernel_context(gru->
gs_gts[i]))
121 inuse_asid = gru->
gs_gts[
i]->ts_gms->ms_asids[
gid].mt_asid;
122 gru_dbg(grudev,
"gid %d, gts %p, gms %p, inuse 0x%x, cxt %d\n",
125 if (inuse_asid == asid) {
134 asid = gru_wrap_asid(gru);
139 if ((inuse_asid > asid) && (inuse_asid < limit))
144 gru_dbg(grudev,
"gid %d, new asid 0x%x, new_limit 0x%x\n", gru->
gs_gid,
150 static int gru_assign_asid(
struct gru_state *gru)
157 asid = gru_reset_asid_limit(gru, asid);
167 static unsigned long reserve_resources(
unsigned long *
p,
int n,
int mmax,
170 unsigned long bits = 0;
199 static void reserve_gru_resources(
struct gru_state *gru,
210 static void free_gru_resources(
struct gru_state *gru,
225 static int check_gru_resources(
struct gru_state *gru,
int cbr_au_count,
226 int dsr_au_count,
int max_active_contexts)
237 static int gru_load_mm_tracker(
struct gru_state *gru,
242 unsigned short ctxbitmap = (1 << gts->
ts_ctxnum);
251 asid = gru_assign_asid(gru);
267 "gid %d, gts %p, gms %p, ctxnum %d, asid 0x%x, asidmap 0x%lx\n",
273 static void gru_unload_mm_tracker(
struct gru_state *gru,
278 unsigned short ctxbitmap;
286 gru_dbg(grudev,
"gid %d, gts %p, gms %p, ctxnum 0x%d, asidmap 0x%lx\n",
324 int cbr_au_count,
int dsr_au_count,
325 unsigned char tlb_preload_count,
int options,
int tsid)
361 gru_dbg(grudev,
"alloc gts %p\n", gts);
366 return ERR_CAST(gms);
381 INIT_LIST_HEAD(&vdata->
vd_head);
383 gru_dbg(grudev,
"alloc vdata %p\n", vdata);
397 gts = gru_find_current_gts_nolock(vdata, tsid);
399 gru_dbg(grudev,
"vma %p, gts %p\n", vma, gts);
421 ngts = gru_find_current_gts_nolock(vdata, tsid);
425 STAT(gts_double_allocate);
430 gru_dbg(grudev,
"vma %p, gts %p\n", vma, gts);
446 free_gru_resources(gru, gts);
462 static void prefetch_data(
void *p,
int num,
int stride)
470 static inline long gru_copy_handle(
void *
d,
void *
s)
476 static void gru_prefetch_context(
void *gseg,
void *
cb,
void *cbe,
477 unsigned long cbrmap,
unsigned long length)
492 static void gru_load_context_data(
void *save,
void *grubase,
int ctxnum,
493 unsigned long cbrmap,
unsigned long dsrmap,
496 void *gseg, *
cb, *cbe;
504 gru_prefetch_context(gseg, cb, cbe, cbrmap, length);
508 save += gru_copy_handle(cb, save);
528 static void gru_unload_context_data(
void *save,
void *grubase,
int ctxnum,
529 unsigned long cbrmap,
unsigned long dsrmap)
531 void *gseg, *cb, *cbe;
545 gru_prefetch_context(gseg, cb, cbe, cbrmap, length);
548 save += gru_copy_handle(save, cb);
549 save += gru_copy_handle(save, cbe + i * GRU_HANDLE_STRIDE);
561 if (!is_kernel_context(gts))
565 gru_dbg(grudev,
"gts %p, cbrmap 0x%lx, dsrmap 0x%lx\n",
567 lock_cch_handle(cch);
571 if (!is_kernel_context(gts))
572 gru_unload_mm_tracker(gru, gts);
582 unlock_cch_handle(cch);
584 gru_free_gru_context(gts);
598 lock_cch_handle(cch);
617 if (is_kernel_context(gts)) {
626 asid = gru_load_mm_tracker(gru, gts);
627 for (i = 0; i < 8; i++) {
636 "err %d: cch %p, gts %p, cbr 0x%lx, dsr 0x%lx\n",
646 unlock_cch_handle(cch);
648 gru_dbg(grudev,
"gid %d, gts %p, cbrmap 0x%lx, dsrmap 0x%lx, tie %d, tis %d\n",
666 lock_cch_handle(cch);
672 for (i = 0; i < 8; i++)
684 unlock_cch_handle(cch);
712 static int gru_check_chiplet_assignment(
struct gru_state *gru,
720 blade_id = uv_numa_blade_id();
745 if (!gru_check_chiplet_assignment(gru, gts)) {
746 STAT(check_context_unload);
748 }
else if (gru_retarget_intr(gts)) {
749 STAT(check_context_retarget_intr);
758 #define next_ctxnum(n) ((n) < GRU_NUM_CCH - 2 ? (n) + 1 : 0)
759 #define next_gru(b, g) (((g) < &(b)->bs_grus[GRU_CHIPLETS_PER_BLADE - 1]) ? \
760 ((g)+1) : &(b)->bs_grus[0])
765 if (is_kernel_context(gts))
774 if (is_kernel_context(gts)) {
776 STAT(steal_kernel_context);
779 STAT(steal_user_context);
788 int ctxnum, ctxnum0,
flag = 0, cbr, dsr;
793 blade_id = uv_numa_blade_id();
809 if (gru_check_chiplet_assignment(gru, gts)) {
810 if (check_gru_resources(gru, cbr, dsr, GRU_NUM_CCH))
814 if (flag && gru == gru0 && ctxnum == ctxnum0)
816 ngts = gru->
gs_gts[ctxnum];
823 if (ngts && is_gts_stealable(ngts, blade))
828 if (ngts || (flag && gru == gru0 && ctxnum == ctxnum0))
831 if (flag && gru == gru0)
840 gts->
ustats.context_stolen++;
843 gts_stolen(ngts, blade);
845 STAT(steal_context_failed);
848 "stole gid %d, ctxnum %d from gts %p. Need cb %d, ds %d;"
849 " avail cb %ld, ds %ld\n",
857 static int gru_assign_context_number(
struct gru_state *gru)
872 int i, max_active_contexts;
876 blade_id = uv_numa_blade_id();
881 if (!gru_check_chiplet_assignment(grux, gts))
885 max_active_contexts)) {
888 if (max_active_contexts == 0)
900 reserve_gru_resources(gru, gts);
903 gts->
ts_ctxnum = gru_assign_context_number(gru);
908 STAT(assign_context);
910 "gseg %p, gts %p, gid %d, ctx %d, cbr %d, dsr %d\n",
915 gru_dbg(grudev,
"failed to allocate a GTS %s\n",
"");
916 STAT(assign_context_failed);
934 vaddr = (
unsigned long)vmf->virtual_address;
935 gru_dbg(grudev,
"vma %p, vaddr 0x%lx (0x%lx)\n",
942 return VM_FAULT_SIGBUS;
951 STAT(load_user_context);
971 return VM_FAULT_NOPAGE;