|
Packit |
345191 |
/*
|
|
Packit |
345191 |
* Copyright (C) 2014 - 2018 Intel Corporation.
|
|
Packit |
345191 |
* All rights reserved.
|
|
Packit |
345191 |
*
|
|
Packit |
345191 |
* Redistribution and use in source and binary forms, with or without
|
|
Packit |
345191 |
* modification, are permitted provided that the following conditions are met:
|
|
Packit |
345191 |
* 1. Redistributions of source code must retain the above copyright notice(s),
|
|
Packit |
345191 |
* this list of conditions and the following disclaimer.
|
|
Packit |
345191 |
* 2. Redistributions in binary form must reproduce the above copyright notice(s),
|
|
Packit |
345191 |
* this list of conditions and the following disclaimer in the documentation
|
|
Packit |
345191 |
* and/or other materials provided with the distribution.
|
|
Packit |
345191 |
*
|
|
Packit |
345191 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS
|
|
Packit |
345191 |
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
Packit |
345191 |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
Packit |
345191 |
* EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
Packit |
345191 |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
Packit |
345191 |
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
Packit |
345191 |
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
Packit |
345191 |
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
Packit |
345191 |
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
Packit |
345191 |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
345191 |
*/
|
|
Packit |
345191 |
|
|
Packit |
345191 |
#include <memkind/internal/memkind_hbw.h>
|
|
Packit |
345191 |
|
|
Packit |
345191 |
#include <stdlib.h>
|
|
Packit |
345191 |
#include <stdio.h>
|
|
Packit |
345191 |
#include <sys/types.h>
|
|
Packit |
345191 |
#include <sys/stat.h>
|
|
Packit |
345191 |
#include <unistd.h>
|
|
Packit |
345191 |
#include <fcntl.h>
|
|
Packit |
345191 |
#include <numaif.h>
|
|
Packit |
345191 |
#include <errno.h>
|
|
Packit |
345191 |
#include <fstream>
|
|
Packit |
345191 |
#include <sstream>
|
|
Packit |
345191 |
#include <iostream>
|
|
Packit |
345191 |
#include <fstream>
|
|
Packit |
345191 |
#include <string>
|
|
Packit |
345191 |
#include <cstring>
|
|
Packit |
345191 |
#include <numa.h>
|
|
Packit |
345191 |
#include <errno.h>
|
|
Packit |
345191 |
|
|
Packit |
345191 |
#include "check.h"
|
|
Packit |
345191 |
|
|
Packit |
345191 |
|
|
Packit |
345191 |
using namespace std;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
|
|
Packit |
345191 |
/*Check each page between the start
|
|
Packit |
345191 |
and the end address additionally also
|
|
Packit |
345191 |
check the end address for pagesize*/
|
|
Packit |
345191 |
Check::Check(const void *p, const trial_t &trial): Check(p, trial.size,
|
|
Packit |
345191 |
trial.page_size)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
Check::Check(const void *p, const size_t size, const size_t page_size)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
const size_t min_page_size = 4096;
|
|
Packit |
345191 |
this->ptr = p;
|
|
Packit |
345191 |
this->size = size;
|
|
Packit |
345191 |
size_t psize = (page_size >= min_page_size ? page_size : min_page_size);
|
|
Packit |
345191 |
if (p && size && psize) {
|
|
Packit |
345191 |
num_address = size / psize;
|
|
Packit |
345191 |
num_address += size % psize ? 1 : 0;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
address = new void *[num_address];
|
|
Packit |
345191 |
size_t i;
|
|
Packit |
345191 |
for (i = 0; i < num_address - 1; ++i) {
|
|
Packit |
345191 |
address[i] = (char *)ptr + i * psize;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
address[i] = (char *)p + size - 1;
|
|
Packit |
345191 |
} else {
|
|
Packit |
345191 |
address = NULL;
|
|
Packit |
345191 |
num_address = 0;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
Check::~Check()
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
delete[] address;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
Check::Check(const Check &other)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
num_address = other.num_address;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
address = new void *[num_address];
|
|
Packit |
345191 |
for (size_t i = 0; i < num_address; ++i) {
|
|
Packit |
345191 |
address[i] = other.address[i];
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
int Check::check_zero(void)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
size_t i;
|
|
Packit |
345191 |
const char *cptr = (char *)ptr;
|
|
Packit |
345191 |
for (i = 0; i < size; ++i) {
|
|
Packit |
345191 |
if (cptr[i] != '\0') {
|
|
Packit |
345191 |
return -1;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
return 0;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
int Check::check_align(size_t align)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
return (size_t)ptr % align;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
string Check::skip_to_next_entry (ifstream &ip)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
string temp, token;
|
|
Packit |
345191 |
size_t found = 0;
|
|
Packit |
345191 |
string empty ="";
|
|
Packit |
345191 |
|
|
Packit |
345191 |
while (!ip.eof()) {
|
|
Packit |
345191 |
getline (ip, temp);
|
|
Packit |
345191 |
found = temp.find("-");
|
|
Packit |
345191 |
if (found != string::npos) {
|
|
Packit |
345191 |
istringstream iss(temp);
|
|
Packit |
345191 |
getline(iss, token, ' ');
|
|
Packit |
345191 |
return token;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
return empty;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
string Check::skip_to_next_kpage(ifstream &ip)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
string temp, token;
|
|
Packit |
345191 |
size_t found = 0;
|
|
Packit |
345191 |
string empty ="";
|
|
Packit |
345191 |
|
|
Packit |
345191 |
while (!ip.eof()) {
|
|
Packit |
345191 |
getline (ip, temp);
|
|
Packit |
345191 |
found = temp.find("KernelPageSize:");
|
|
Packit |
345191 |
if (found != string::npos) {
|
|
Packit |
345191 |
return temp;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
return empty;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
|
|
Packit |
345191 |
void Check::get_address_range(string &line,
|
|
Packit |
345191 |
unsigned long long *start_addr,
|
|
Packit |
345191 |
unsigned long long *end_addr)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
stringstream ss(line);
|
|
Packit |
345191 |
string token;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
getline(ss, token, '-');
|
|
Packit |
345191 |
*start_addr = strtoul(token.c_str(),
|
|
Packit |
345191 |
NULL,
|
|
Packit |
345191 |
16);
|
|
Packit |
345191 |
getline(ss, token, '-');
|
|
Packit |
345191 |
*end_addr = strtoul(token.c_str(),
|
|
Packit |
345191 |
NULL,
|
|
Packit |
345191 |
16);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
size_t Check::get_kpagesize(string line)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
stringstream ss(line);
|
|
Packit |
345191 |
string token;
|
|
Packit |
345191 |
size_t pagesize;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
|
|
Packit |
345191 |
ss >> token;
|
|
Packit |
345191 |
ss >> token;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
pagesize = atol(token.c_str());
|
|
Packit |
345191 |
|
|
Packit |
345191 |
return (size_t)pagesize;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
int Check::check_page_size(size_t page_size)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
int err = 0;
|
|
Packit |
345191 |
size_t i;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
ip.open ("/proc/self/smaps");
|
|
Packit |
345191 |
|
|
Packit |
345191 |
populate_smaps_table();
|
|
Packit |
345191 |
if (check_page_size(page_size, address[0])) {
|
|
Packit |
345191 |
err = -1;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
for (i = 1; i < num_address && !err; ++i) {
|
|
Packit |
345191 |
if (check_page_size(page_size, address[i])) {
|
|
Packit |
345191 |
err = i;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
return err;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
int Check::populate_smaps_table ()
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
string read;
|
|
Packit |
345191 |
size_t lpagesize;
|
|
Packit |
345191 |
smaps_entry_t lentry;
|
|
Packit |
345191 |
unsigned long long start_addr;
|
|
Packit |
345191 |
unsigned long long end_addr;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
ip >> read;
|
|
Packit |
345191 |
while (!ip.eof()) {
|
|
Packit |
345191 |
|
|
Packit |
345191 |
start_addr = end_addr = 0;
|
|
Packit |
345191 |
get_address_range (read,
|
|
Packit |
345191 |
&start_addr,
|
|
Packit |
345191 |
&end_addr);
|
|
Packit |
345191 |
read = skip_to_next_kpage(ip);
|
|
Packit |
345191 |
getline(ip, read);
|
|
Packit |
345191 |
lpagesize = get_kpagesize(read);
|
|
Packit |
345191 |
lpagesize *= 1024;
|
|
Packit |
345191 |
lentry.start_addr = start_addr;
|
|
Packit |
345191 |
lentry.end_addr = end_addr;
|
|
Packit |
345191 |
lentry.pagesize = lpagesize;
|
|
Packit |
345191 |
smaps_table.push_back(lentry);
|
|
Packit |
345191 |
read = skip_to_next_entry(ip);
|
|
Packit |
345191 |
if (read.empty()) {
|
|
Packit |
345191 |
break;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
if (0 == smaps_table.size()) {
|
|
Packit |
345191 |
fprintf(stderr,"Empty smaps table\n");
|
|
Packit |
345191 |
return -1;
|
|
Packit |
345191 |
} else {
|
|
Packit |
345191 |
return 0;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
int Check::check_page_size(size_t page_size, void *vaddr)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
string read;
|
|
Packit |
345191 |
unsigned long long virt_addr;
|
|
Packit |
345191 |
size_t lpagesize;
|
|
Packit |
345191 |
list<smaps_entry_t>::iterator it;
|
|
Packit |
345191 |
unsigned long long start_addr;
|
|
Packit |
345191 |
unsigned long long end_addr;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
virt_addr = (unsigned long long)(vaddr);
|
|
Packit |
345191 |
|
|
Packit |
345191 |
for (it = smaps_table.begin();
|
|
Packit |
345191 |
it != smaps_table.end();
|
|
Packit |
345191 |
it++) {
|
|
Packit |
345191 |
|
|
Packit |
345191 |
start_addr = it->start_addr;
|
|
Packit |
345191 |
end_addr = it->end_addr;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
if ((virt_addr >= start_addr) &&
|
|
Packit |
345191 |
(virt_addr < end_addr)) {
|
|
Packit |
345191 |
lpagesize = it->pagesize;
|
|
Packit |
345191 |
if (lpagesize == page_size) {
|
|
Packit |
345191 |
return 0;
|
|
Packit |
345191 |
} else {
|
|
Packit |
345191 |
/*The pagesize of allocation and req don't match*/
|
|
Packit |
345191 |
fprintf(stderr,"%zd does not match entry in SMAPS (%zd)\n",
|
|
Packit |
345191 |
page_size, lpagesize);
|
|
Packit |
345191 |
return -1;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
/*Never found a match!*/
|
|
Packit |
345191 |
return 1;
|
|
Packit |
345191 |
}
|