Viewing file: mem_refcnt.c (5.99 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* $Id$ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc. * Copyright (C) 2000 by Colin Ngam */
#include <linux/types.h> #include <asm/sn/sgi.h> #include <asm/sn/invent.h> #include <asm/sn/hcl.h> #include <asm/sn/hcl_util.h> #include <asm/sn/nodepda.h> #include <asm/sn/hubspc.h> #include <asm/sn/iograph.h> #include <asm/sn/mem_refcnt.h> #include <asm/sn/hwcntrs.h> // From numa_hw.h
#define MIGR_COUNTER_MAX_GET(nodeid) \ (NODEPDA_MCD((nodeid))->migr_system_kparms.migr_threshold_reference) /* * Get the Absolute Theshold */ #define MIGR_THRESHOLD_ABS_GET(nodeid) ( \ MD_MIG_VALUE_THRESH_GET(COMPACT_TO_NASID_NODEID(nodeid))) /* * Get the current Differential Threshold */ #define MIGR_THRESHOLD_DIFF_GET(nodeid) \ (NODEPDA_MCD(nodeid)->migr_as_kparms.migr_base_threshold)
#define NUM_OF_HW_PAGES_PER_SW_PAGE() (NBPP / MD_PAGE_SIZE)
// #include "migr_control.h"
int mem_refcnt_attach(devfs_handle_t hub) { devfs_handle_t refcnt_dev; hwgraph_char_device_add(hub, "refcnt", "hubspc_", &refcnt_dev); device_info_set(refcnt_dev, (void*)(ulong)HUBSPC_REFCOUNTERS);
return (0); }
/*ARGSUSED*/ int mem_refcnt_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp) { cnodeid_t node;
ASSERT( (hubspc_subdevice_t)(ulong)device_info_get(*devp) == HUBSPC_REFCOUNTERS );
node = master_node_get(*devp);
ASSERT( (node >= 0) && (node < numnodes) );
if (NODEPDA(node)->migr_refcnt_counterbuffer == NULL) { return (ENODEV); }
ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL ); ASSERT( NODEPDA(node)->migr_refcnt_cbsize != (size_t)0 );
return (0); }
/*ARGSUSED*/ int mem_refcnt_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp) { return 0; }
/*ARGSUSED*/ int mem_refcnt_mmap(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot) { cnodeid_t node; int errcode; char* buffer; size_t blen; ASSERT( (hubspc_subdevice_t)(ulong)device_info_get(dev) == HUBSPC_REFCOUNTERS );
node = master_node_get(dev);
ASSERT( (node >= 0) && (node < numnodes) );
ASSERT( NODEPDA(node)->migr_refcnt_counterbuffer != NULL); ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL ); ASSERT( NODEPDA(node)->migr_refcnt_cbsize != 0 );
/* * XXXX deal with prot's somewhere around here.... */
buffer = NODEPDA(node)->migr_refcnt_counterbuffer; blen = NODEPDA(node)->migr_refcnt_cbsize;
/* * Force offset to be a multiple of sizeof(refcnt_t) * We round up. */
off = (((off - 1)/sizeof(refcnt_t)) + 1) * sizeof(refcnt_t);
if ( ((buffer + blen) - (buffer + off + len)) < 0 ) { return (EPERM); }
errcode = v_mapphys(vt, buffer + off, len);
return errcode; }
/*ARGSUSED*/ int mem_refcnt_unmap(devfs_handle_t dev, vhandl_t *vt) { return 0; }
/* ARGSUSED */ int mem_refcnt_ioctl(devfs_handle_t dev, int cmd, void *arg, int mode, cred_t *cred_p, int *rvalp) { cnodeid_t node; int errcode; extern int numnodes; ASSERT( (hubspc_subdevice_t)(ulong)device_info_get(dev) == HUBSPC_REFCOUNTERS );
node = master_node_get(dev);
ASSERT( (node >= 0) && (node < numnodes) );
ASSERT( NODEPDA(node)->migr_refcnt_counterbuffer != NULL); ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL ); ASSERT( NODEPDA(node)->migr_refcnt_cbsize != 0 );
errcode = 0; switch (cmd) { case RCB_INFO_GET: { rcb_info_t rcb; rcb.rcb_len = NODEPDA(node)->migr_refcnt_cbsize; rcb.rcb_sw_sets = NODEPDA(node)->migr_refcnt_numsets; rcb.rcb_sw_counters_per_set = numnodes; rcb.rcb_sw_counter_size = sizeof(refcnt_t);
rcb.rcb_base_pages = NODEPDA(node)->migr_refcnt_numsets / NUM_OF_HW_PAGES_PER_SW_PAGE(); rcb.rcb_base_page_size = NBPP; rcb.rcb_base_paddr = ctob(slot_getbasepfn(node, 0)); rcb.rcb_cnodeid = node; rcb.rcb_granularity = MD_PAGE_SIZE; #ifdef LATER rcb.rcb_hw_counter_max = MIGR_COUNTER_MAX_GET(node); rcb.rcb_diff_threshold = MIGR_THRESHOLD_DIFF_GET(node); #endif rcb.rcb_abs_threshold = MIGR_THRESHOLD_ABS_GET(node); rcb.rcb_num_slots = node_getnumslots(node);
if (COPYOUT(&rcb, arg, sizeof(rcb_info_t))) { errcode = EFAULT; }
break; } case RCB_SLOT_GET: { rcb_slot_t slot[MAX_MEM_SLOTS]; int s; int nslots;
nslots = node_getnumslots(node); ASSERT(nslots <= MAX_MEM_SLOTS); for (s = 0; s < nslots; s++) { slot[s].base = (uint64_t)ctob(slot_getbasepfn(node, s)); #ifdef LATER slot[s].size = (uint64_t)ctob(slot_getsize(node, s)); #else slot[s].size = (uint64_t)1; #endif } if (COPYOUT(&slot[0], arg, nslots * sizeof(rcb_slot_t))) { errcode = EFAULT; } *rvalp = nslots; break; } default: errcode = EINVAL; break;
} return errcode; }
|