针对NOVA(NVMFS)文件系模拟PM(Persistent Memory)

版权声明:本文为博主原创文章,未经博主允许不得转载 https://blog.csdn.net/qq_34018840/article/details/79883039

PM的模拟

      参考链接:如何模拟PM。但是这样使用DRAM模拟出来的PM在未做任何修改(添加写入延迟)的情况下实际是以DRAM速度在进行读写访问。

添加写入延迟

      通过在系统的cflush操作后添加写入延迟(个人添加为150ns)来模拟PM。具体操作为:

      1、将头文件latency.h放入目录/linux-nova/linux-nova/include/linux下,latency.h的代码如下所示。

/* Emulate latency */
#undef PCM_EMULATE_LATENCY
#define PCM_EMULATE_LATENCY 0x1

/* CPU frequency */
#define PCM_CPUFREQ 2100LLU /* GHz */

/* PCM write latency*/
#define PCM_LATENCY_WRITE 150 /* ns */

/* PCM write bandwidth */
#define PCM_BANDWIDTH_MB 4000
//#define PCM_BANDWIDTH_MB 600
//#define PCM_BANDWIDTH_MB 300
//2000:150ns(PCM speed in theory),300:1000ns(practical speed of PCM),150:2000ns

/* DRAM system peak bandwidth */
#define DRAM_BANDWIDTH_MB 24000

#define NS2CYCLE(__ns) ((__ns) * PCM_CPUFREQ / 1000)
#define CYCLE2NS(__cycles) ((__cycles) * 1000 / PCM_CPUFREQ)

#define gethrtime       asm_rdtsc

/* Public types */
typedef uint64_t pcm_hrtime_t;

#if defined(__i386__)

static inline unsigned long long asm_rdtsc(void)
{
	unsigned long long int x;
	__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
	return x;
}

static inline unsigned long long asm_rdtscp(void)
{
		unsigned hi, lo;
	__asm__ __volatile__ ("rdtscp" : "=a"(lo), "=d"(hi)::"ecx");
    return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );

}
#elif defined(__x86_64__)

static inline unsigned long long asm_rdtsc(void)
{
	unsigned hi, lo;
	__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
    return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}

static inline unsigned long long asm_rdtscp(void)
{
	unsigned hi, lo;
	__asm__ __volatile__ ("rdtscp" : "=a"(lo), "=d"(hi)::"rcx");
    return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}
#else
#error "What architecture is this???"
#endif


static inline
void
emulate_latency_ns(int ns)
{
	pcm_hrtime_t cycles;
	pcm_hrtime_t start;
	pcm_hrtime_t stop;
	
	start = asm_rdtsc();
	cycles = NS2CYCLE(((ns + 63) / 64) * PCM_LATENCY_WRITE);

	do { 
		/* RDTSC doesn't necessarily wait for previous instructions to complete 
		 * so a serializing instruction is usually used to ensure previous 
		 * instructions have completed. However, in our case this is a desirable
		 * property since we want to overlap the latency we emulate with the
		 * actual latency of the emulated instruction. 
		 */
		stop = asm_rdtsc();
	} while (stop - start < cycles);
}

      2、修改/linux-nova/fs/fs/nova目录下的nova_def.h头文件中的nova_flush_buffer()函数如下图所示,添加最后三行代码,并在文件开头添加引用#include <linux/latency.h>。其中emulate_latency_ns()函数为头文件latency.h中的。

      3、之后重新在/linux-nova/fs/nova目录下编译nova模块,完成挂载即可。

猜你喜欢

转载自blog.csdn.net/qq_34018840/article/details/79883039