Linux gup

BEV(二)多frames融合 当前帧的LIDAR数据** 阅读详情
/**
 * __get_user_pages() - pin user pages in memory
 * @tsk:	task_struct of target task
 * @mm:		mm_struct of target mm
 * @start:	starting user address
 * @nr_pages:	number of pages from start to pin
 * @gup_flags:	flags modifying pin behaviour
 * @pages:	array that receives pointers to the pages pinned.
 *		Should be at least nr_pages long. Or NULL, if caller
 *		only intends to ensure the pages are faulted in.
 * @vmas:	array of pointers to vmas corresponding to each page.
 *		Or NULL if the caller does not require them.
 * @nonblocking: whether waiting for disk IO or mmap_sem contention
 *
 * Returns number of pages pinned. This may be fewer than the number
 * requested. If nr_pages is 0 or negative, returns 0. If no pages
 * were pinned, returns -errno. Each page returned must be released
 * with a put_page() call when it is finished with. vmas will only
 * remain valid while mmap_sem is held.
 *
 * Must be called with mmap_sem held.  It may be released.  See below.
 *
 * __get_user_pages walks a process's page tables and takes a reference to
 * each struct page that each user address corresponds to at a given
 * instant. That is, it takes the page that would be accessed if a user
 * thread accesses the given user virtual address at that instant.
 *
 * This does not guarantee that the page exists in the user mappings when
 * __get_user_pages returns, and there may even be a completely different
 * page there in some cases (eg. if mmapped pagecache has been invalidated
 * and subsequently re faulted). However it does guarantee that the page
 * won't be freed completely. And mostly callers simply care that the page
 * contains data that was valid *at some point in time*. Typically, an IO
 * or similar operation cannot guarantee anything stronger anyway because
 * locks can't be held over the syscall boundary.
 *
 * If @gup_flags & FOLL_WRITE == 0, the page must not be written to. If
 * the page is written to, set_page_dirty (or set_page_dirty_lock, as
 * appropriate) must be called after the page is finished with, and
 * before put_page is called.
 *
 * If @nonblocking != NULL, __get_user_pages will not wait for disk IO
 * or mmap_sem contention, and if waiting is needed to pin all pages,
 * *@nonblocking will be set to 0.  Further, if @gup_flags does not
 * include FOLL_NOWAIT, the mmap_sem will be released via up_read() in
 * this case.
 *
 * A caller using such a combination of @nonblocking and @gup_flags
 * must therefore hold the mmap_sem for reading only, and recognize
 * when it's been released.  Otherwise, it must be held for either
 * reading or writing and will not be released.
 *
 * In most cases, get_user_pages or get_user_pages_fast should be used
 * instead of __get_user_pages. __get_user_pages should be used only if
 * you need some special @gup_flags.
 */
static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
		unsigned long start, unsigned long nr_pages,
		unsigned int gup_flags, struct page **pages,
		struct vm_area_struct **vmas, int *nonblocking)
{
	long i = 0;
	unsigned int page_mask;
	struct vm_area_struct *vma = NULL;

	if (!nr_pages)
		return 0;

	VM_BUG_ON(!!pages != !!(gup_flags & FOLL_GET));

	/*
	 * If FOLL_FORCE is set then do not force a full fault as the hinting
	 * fault information is unrelated to the reference behaviour of a task
	 * using the address space
	 */
	if (!(gup_flags & FOLL_FORCE))
		gup_flags |= FOLL_NUMA;

	do {
		struct page *page;
		unsigned int foll_flags = gup_flags;
		unsigned int page_increm;

		/* first iteration or cross vma bound */
		if (!vma || start >= vma->vm_end) {
			vma = find_extend_vma(mm, start);
			if (!vma && in_gate_area(mm, start)) {
				int ret;
				ret = get_gate_page(mm, start & PAGE_MASK,
						gup_flags, &vma,
						pages ? &pages[i] : NULL);
				if (ret)
					return i ? : ret;
				page_mask = 0;
				goto next_page;
			}

			if (!vma || check_vma_flags(vma, gup_flags))
				return i ? : -EFAULT;
			if (is_vm_hugetlb_page(vma)) {
				i = follow_hugetlb_page(mm, vma, pages, vmas,
						&start, &nr_pages, i,
						gup_flags);
				continue;
			}
		}
retry:
		/*
		 * If we have a pending SIGKILL, don't keep faulting pages and
		 * potentially allocating memory.
		 */
		if (unlikely(fatal_signal_pending(current)))
			return i ? i : -ERESTARTSYS;
		cond_resched();
		page = follow_page_mask(vma, start, foll_flags, &page_mask);
		if (!page) {
			int ret;
			ret = faultin_page(tsk, vma, start, &foll_flags,
					nonblocking);
			switch (ret) {
			case 0:
				goto retry;
			case -EFAULT:
			case -ENOMEM:
			case -EHWPOISON:
				return i ? i : ret;
			case -EBUSY:
				return i;
			case -ENOENT:
				goto next_page;
			}
			BUG();
		} else if (PTR_ERR(page) == -EEXIST) {
			/*
			 * Proper page table entry exists, but no corresponding
			 * struct page.
			 */
			goto next_page;
		} else if (IS_ERR(page)) {
			return i ? i : PTR_ERR(page);
		}
		if (pages) {
			pages[i] = page;
			flush_anon_page(vma, page, start);
			flush_dcache_page(page);
			page_mask = 0;
		}
next_page:
		if (vmas) {
			vmas[i] = vma;
			page_mask = 0;
		}
		page_increm = 1 + (~(start >> PAGE_SHIFT) & page_mask);
		if (page_increm > nr_pages)
			page_increm = nr_pages;
		i += page_increm;
		start += page_increm * PAGE_SIZE;
		nr_pages -= page_increm;
	} while (nr_pages);
	return i;
}

__get_user_pages() - pin user pages in memory 表明 使用该函数可以锁住物理页,防止其被swap出去或者被migrate 。

static inline void get_page(struct page *page)
{
	page = compound_head(page);
	/*
	 * Getting a normal page or the head of a compound page
	 * requires to already have an elevated page->_refcount.
	 */
	VM_BUG_ON_PAGE(page_ref_count(page) <= 0, page);
	page_ref_inc(page);

	if (unlikely(is_zone_device_page(page)))
		get_zone_device_page(page);
}

参考:https://zhuanlan.zhihu.com/p/28742793
Linux内核提供的pin机制是gup(参考mm/gup.c),这是get_user_pages系列函数的缩写。它的作用是把某个进程的虚拟地址进行预缺页,把物理页表分配出来,然后做get_page(),增加这个page的使用计数,这样这个page就不会被释放,设备就可以一直访问这个物理页了。
以 v4l2 使用说明

/**
 * vb2_create_framevec() - map virtual addresses to pfns
 * @start:	Virtual user address where we start mapping
 * @length:	Length of a range to map
 * @write:	Should we map for writing into the area
 *
 * This function allocates and fills in a vector with pfns corresponding to
 * virtual address range passed in arguments. If pfns have corresponding pages,
 * page references are also grabbed to pin pages in memory. The function
 * returns pointer to the vector on success and error pointer in case of
 * failure. Returned vector needs to be freed via vb2_destroy_pfnvec().
 */
struct frame_vector *vb2_create_framevec(unsigned long start,
					 unsigned long length,
					 bool write)
{
	int ret;
	unsigned long first, last;
	unsigned long nr;
	struct frame_vector *vec;
	unsigned int flags = FOLL_FORCE;

	if (write)
		flags |= FOLL_WRITE;

	first = start >> PAGE_SHIFT;
	last = (start + length - 1) >> PAGE_SHIFT;
	nr = last - first + 1;
	vec = frame_vector_create(nr);
	if (!vec)
		return ERR_PTR(-ENOMEM);
	ret = get_vaddr_frames(start & PAGE_MASK, nr, flags, vec);
	if (ret < 0)
		goto out_destroy;
	/* We accept only complete set of PFNs */
	if (ret != nr) {
		ret = -EFAULT;
		goto out_release;
	}
	return vec;
out_release:
	put_vaddr_frames(vec);
out_destroy:
	frame_vector_destroy(vec);
	return ERR_PTR(ret);
}
EXPORT_SYMBOL(vb2_create_framevec);
/**
 * get_vaddr_frames() - map virtual addresses to pfns
 * @start:	starting user address
 * @nr_frames:	number of pages / pfns from start to map
 * @gup_flags:	flags modifying lookup behaviour
 * @vec:	structure which receives pages / pfns of the addresses mapped.
 *		It should have space for at least nr_frames entries.
 *
 * This function maps virtual addresses from @start and fills @vec structure
 * with page frame numbers or page pointers to corresponding pages (choice
 * depends on the type of the vma underlying the virtual address). If @start
 * belongs to a normal vma, the function grabs reference to each of the pages
 * to pin them in memory. If @start belongs to VM_IO | VM_PFNMAP vma, we don't
 * touch page structures and the caller must make sure pfns aren't reused for
 * anything else while he is using them.
 *
 * The function returns number of pages mapped which may be less than
 * @nr_frames. In particular we stop mapping if there are more vmas of
 * different type underlying the specified range of virtual addresses.
 * When the function isn't able to map a single page, it returns error.
 *
 * This function takes care of grabbing mmap_sem as necessary.
 */
int get_vaddr_frames(unsigned long start, unsigned int nr_frames,
		     unsigned int gup_flags, struct frame_vector *vec)
{
	struct mm_struct *mm = current->mm;
	struct vm_area_struct *vma;
	int ret = 0;
	int err;
	int locked;

	if (nr_frames == 0)
		return 0;

	if (WARN_ON_ONCE(nr_frames > vec->nr_allocated))
		nr_frames = vec->nr_allocated;

	down_read(&mm->mmap_sem);
	locked = 1;
	vma = find_vma_intersection(mm, start, start + 1);
	if (!vma) {
		ret = -EFAULT;
		goto out;
	}

	/*
	 * While get_vaddr_frames() could be used for transient (kernel
	 * controlled lifetime) pinning of memory pages all current
	 * users establish long term (userspace controlled lifetime)
	 * page pinning. Treat get_vaddr_frames() like
	 * get_user_pages_longterm() and disallow it for filesystem-dax
	 * mappings.
	 */
	if (vma_is_fsdax(vma)) {
		ret = -EOPNOTSUPP;
		goto out;
	}

	if (!(vma->vm_flags & (VM_IO | VM_PFNMAP))) {
		vec->got_ref = true;
		vec->is_pfns = false;
		ret = get_user_pages_locked(start, nr_frames,
			gup_flags, (struct page **)(vec->ptrs), &locked);
		goto out;
	}

	vec->got_ref = false;
	vec->is_pfns = true;
	do {
		unsigned long *nums = frame_vector_pfns(vec);

		while (ret < nr_frames && start + PAGE_SIZE <= vma->vm_end) {
			err = follow_pfn(vma, start, &nums[ret]);
			if (err) {
				if (ret == 0)
					ret = err;
				goto out;
			}
			start += PAGE_SIZE;
			ret++;
		}
		/*
		 * We stop if we have enough pages or if VMA doesn't completely
		 * cover the tail page.
		 */
		if (ret >= nr_frames || start < vma->vm_end)
			break;
		vma = find_vma_intersection(mm, start, start + 1);
	} while (vma && vma->vm_flags & (VM_IO | VM_PFNMAP));
out:
	if (locked)
		up_read(&mm->mmap_sem);
	if (!ret)
		ret = -EFAULT;
	if (ret > 0)
		vec->nr_frames = ret;
	return ret;
}
EXPORT_SYMBOL(get_vaddr_frames);
/*
 * We can leverage the VM_FAULT_RETRY functionality in the page fault
 * paths better by using either get_user_pages_locked() or
 * get_user_pages_unlocked().
 *
 * get_user_pages_locked() is suitable to replace the form:
 *
 *      down_read(&mm->mmap_sem);
 *      do_something()
 *      get_user_pages(tsk, mm, ..., pages, NULL);
 *      up_read(&mm->mmap_sem);
 *
 *  to:
 *
 *      int locked = 1;
 *      down_read(&mm->mmap_sem);
 *      do_something()
 *      get_user_pages_locked(tsk, mm, ..., pages, &locked);
 *      if (locked)
 *          up_read(&mm->mmap_sem);
 */
long get_user_pages_locked(unsigned long start, unsigned long nr_pages,
			   unsigned int gup_flags, struct page **pages,
			   int *locked)
{
	return __get_user_pages_locked(current, current->mm, start, nr_pages,
				       pages, NULL, locked, true,
				       gup_flags | FOLL_TOUCH);
}
EXPORT_SYMBOL(get_user_pages_locked);

__get_user_pages_locked 会调用到 __get_user_pages,把V4L2使用的这些page在内核pin住。不会出现 migrate page,导致dma 出现buffer 异常。

NVMe CMB 到 DMA-BUF 的内核接口之争 摘要:2016年Linux内核社区围绕NVMe CMB与RDMA直连技术展开激烈争论。Mellanox工程师提出通过DMA-BUF实现设备间内存共享,但遭到Intel和内核大牛的强烈反对。核心矛盾在于:CMB作为专用硬件内存缺乏struct page支持,直接暴露给用户态可能引发硬件故障。内核开发者坚持"先内后外"原则,拒绝妥协底层硬件特性暴露,最终推动形成更安全的P2P架构方案。这场讨论体现了Linux内核在性能优化与稳定性之间的权衡智慧。 阅读详情

相关推荐

linux那些事之gup_flags

linux gup子系统在处理各种pin memory中,为了方便处理各种使用场景同时减少代码冗余,使用了gup_flags 标识位用于标记处理内存时各种场景,也是常见的软件设计方法,但是flag引入增加对代码的维护难度,尤其时阅读代码时经常被各种gup_flags(在include\linux\mm.h文件中定义)搞蒙,因此有必要对gup flags做个说明: 名称 值 说明 FOLL_WRITE 0x01 用于检查对应的page table entry是否拥有写权限 F

weixin_42730667的博客 1916

宋宝华:论Linux的页迁移(Page Migration)完整版

本文目录●●0. 为什么关心Page Migration1. CoW引起的页迁移1.1 fork1.2 KSM2. 内存规整引起的页迁移 2.1 CMA2.2 alloc_p...

宋宝华 4945

linux那些事之pin memory相关API

内核中为pin memory 用户空间申请物理内存除了get_user_pages() API函数之外,还有其他相关一系列函数,主要位于mm\gup.c 主要都是针对get_user_pages进行的扩展,以满足各种不同需求。 pin_user_pages pin_user_pages()为用户空间锁定物理页,与get_user_pages函数基本相同,差别在于gup_flags标志位不同: /** * pin_user_pages() - pin user pages in memory for

weixin_42730667的博客 3145

Linux的页迁移(Page Migration)

对于用户空间的应用程序,我们通常根本不关心page的物理存放位置,因为我们用的是虚拟地址。所以,只要虚拟地址不变,哪怕这个页在物理上从DDR的这里飞到DDR的那里,用户都基本不感知。那么,为什么要写一篇论述页迁移的文章呢? 我认为有2种场景下,你会关注这个Page迁移的问题:一个是在Linux里面写实时程序,尤其是Linux的RT补丁打上后的情况,你希望你的应用有一个确定的时延,不希望跑着跑着你的Page正在换位置而导致的延迟;再一个场景就是在用户空间做DMA的场景,尤其是SVA(SharedVirtua

lx123010的专栏 2104

linux上部署tensorflow-gup

一、安装tensorflow-gpu 1.9.0 TensorFlow官方帮助文档为Ubuntu 16.04提供五种安装方式,我选择原汁原味的第二种方式:Use pip in your system environment: 安装指令没有太多值得讲究的地方,但如果你按照帮助文档去安装,由于天朝伟大的墙的杰作,网速慢如蜗牛,我保证你花一年时间也装不上。该怎么办呢?可以使用国外代理服务器,也可以使用...

赵凯月的博客 386

STM32F103C8T6通过ESP8266连接阿里云物联网平台(附代码)

STM32F103C8T6连接阿里云物联网平台(1)—阿里云lot Studio控制 Web开发 分享一下自己使用stm32f103c8t6通过ESP_01模块连接阿里云物联网平台,实现温湿度上传和控制命令下达的过程,能力有限,用的是最简单的方法,如有错误,多多担待。 一、硬件选型 1、 stm32f103c8t6 2、ESP_01 wifi模块 3、其他 二、硬件连接 WSP_01 STM32F103C8T6 RXD PA2 TXD PA3 RES PA4 VCC 3.3

weixin_A13253323604 3万+

安装GUP-powered Pytorch的另一条出路

直接在Linux系统内安装anaconda,然后直接安装yews,就自动安装好了GUP-powered Pytorch。

weixin_43702064的博客 136

【3D计算机视觉】从PointNet到PointNet++理论及pytorch代码

从PointNet到PointNet++理论及代码详解1. 点云是什么1.1 三维数据的表现形式1.2 为什么使用点云1.3 点云上以往的相关工作2. PointNet2.1 基于点云的置换不变性2.1.1 由对称函数到PointNet(vanilla)2.1.2 理论证明2.2 基于点云的旋转不变性2.3 网络总体结构2.4 实验结果和网络的鲁棒性2.5 代码解析3. PointNet++3.1...

小执着的博客 8万+

宋宝华:论Linux的页迁移(Page Migration)上集

本文目录●●0. 为什么关心Page Migration1. CoW引起的页迁移1.1 fork1.2 KSM2. 内存规整引起的页迁移 2.1 CMA2.2 alloc_p...

宋宝华 1206

Linux 内存 --- get_user_pages_remote 函数

本文介绍了Linux内核中的get_user_pages_remote()函数,该函数用于跨进程获取用户空间内存页的物理页描述符(struct page*)。文章首先分析了函数原型和工作原理,指出其主要用于DMA、零拷贝I/O等场景,但存在无法自动重试缺页的缺陷。随后提供了一个完整的代码示例:用户程序通过mmap分配内存并获取其物理地址,内核模块则通过指定PID和虚拟地址,使用get_user_pages_remote()验证目标进程内存。

小立仔 645

MOOS-ivp 实验三 MOOS简介(1)

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录系列文章目录前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。 提示:以下是本篇文章正文内容,下面案例

weixin_44151170的博客 7404

脏牛(Dirty COW)漏洞学习

脏牛(Dirty COW,全称“Copy-On-Write”漏洞,CVE-2016-5195)是 Linux 内核中的一个严重漏洞。它允许普通用户通过竞争条件)在内核的 COW 机制下获得写入只读映射文件的权限,从而实现本地权限提升(Privilege Escalation)。脏牛漏洞是由于 Linux COW 机制中的竞争条件导致的。该漏洞利用 GUP 机制使攻击者能够修改只读映射的文件。主要的利用方式是mmapmadvise触发竞争。

m0_63753692的博客 1803

用 XCO 库一键找出某个 ABAP 类的全部子类

ABAP XCO库子类枚举技术解析 本文介绍了在ABAP项目中如何利用XCO库高效获取类的继承层次结构。传统方法使用CL_ABAP_CLASSDESCR或手动维护映射表存在效率低、易遗漏的问题。新方法通过XCO库的IF_XCO_AO_CLASS接口,可简洁地获取父类的所有子类(包括间接子类)。 核心API链式调用: 获取类句柄:xco_cp_abap=>class() 导航子类集合:subclasses->all 获取结果:get()返回类引用表或get_names()返回类名列表 典型应用场景

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 110

又一位“内核老匠人”悄悄离开了 Red Hat|一个人一个时代

David 是在 Linux 内核圈名人堂top级的人物,他不是那种喜欢抛头露面的明星工程师,但谁都知道——但你知道,这背后是一段十年工作的收束,一个时代的转身,还有 Red Hat 内核团队必然要面对的一段空窗期。没有仪式,没有官宣,就像他平时写代码一样——能一句话解决的,绝不多用两个字。你动之前,最好看看 David 写过什么,踩过什么,堵过什么。内核圈的“豪放派”和“工匠派”,他是后者,而且是硬核那种。但对熟悉开源生态的人,这是一种“时代细节”的变化。不抢戏,不发声,但关键时刻把系统稳住的人。

IT运维技术圈 360

Linux 内存 --- get_user_pages/pin_user_pages函数

本文介绍了Linux内核中固定用户内存页(pin user pages)的概念及其实现机制。

小立仔 1593

基于3D相机的人体穴位识别与标注系统——完整Python实现方案

摘要 本文提出了一种基于3D相机的人体穴位识别与标注系统完整实现方案。系统采用Intel RealSense D435相机实时采集RGB-D数据,结合MediaPipe Pose模型进行人体33个关键骨骼点的三维姿态估计。通过建立穴位与骨骼关键点的映射关系,利用相机内参和深度信息将二维图像坐标转换为三维空间坐标。系统采用模块化设计,包含数据采集层、算法处理层、坐标转换层和可视化层,实现了穴位定位、三维坐标转换和点云可视化功能。关键技术包括:基于骨度折量法的穴位映射算法、深度图像到三维点云的转换方法,以及Op

AI的内部世界的博客 243

gdb调试器底层实现原理

前几天写了两篇调试器相关的文章《从零手写gdb调试器》《调试器是如何让代码断下来的》,在多个学员群里引发了大家的讨论。没想到大家对调试器这么有热情!今天再来把大家讨论比较多的话题写成文章分享:gdb调试器的底层实现原理

子牙老师 1001

人群仿真软件:Pathfinder_(14).与其他软件的集成与互操作

在人群仿真软件的二次开发中,与其他软件的集成和互操作是非常重要的。通过数据导入导出、接口调用和脚本编写,可以显著提升仿真的准确性和实用性。Pathfinder提供了多种数据格式的支持和丰富的API,使得与其他软件的集成变得简单高效。无论是建筑模型的导入、仿真结果的导出,还是实时数据的交换,Pathfinder都能满足用户的需求。

kkchenjj的博客 1000

字符设备驱动内存管理最佳实践解析

深入探讨字符设备驱动程序中的内存管理技巧,提升驱动程序稳定性与资源利用效率,为内核开发提供可靠支持。

weixin_35364187的博客 535

宋宝华:谈一谈Linux写时拷贝(COW)的安全漏洞(1)

COW技术,爆出了巨大的漏洞,让父子进程间可以向对方泄露写过的新数据,成为了Linux内核的惊天大瓜。

宋宝华 8764

深度学习实战103-基于KDD Cup 99数据集的搭建神经网络的检测系统(NIDS),通过对网络流量数据进行分析,提供完整代码

接下来,我们定义一个全连接神经网络模型。return x# 创建数据集和数据加载器# 初始化模型通过以上步骤,我们实现了一个基于PyTorch的简单网络入侵检测系统。这个系统使用KDD Cup 99数据集进行训练和评估。实际应用中,您可以根据需求调整模型结构、超参数以及数据预处理方法。希望对大家有所帮助!如果有任何问题或需要进一步的解释,请随时咨询。

微学AI的博客 1552

GUP使用率查看命令

首先呢,要使用命令lspci | grep -i vga 查看你的显卡是NVIDIA的还是Intel的。对于NVIDIA的直接装个NVIDIA的驱动就可以查看了( nvidia-smi ),这个网上有教程不多说。对于Intel的显卡,其实道理也是一样的,只是没有方法而已。 Linux 中安装GPU查看工具:sudo apt install intel-gpu-tools 详细用法可以man手册查看 GUP使用率查看命令:intel_gpu_top 渲染空间可能由常规3D操作使..

cat_eat_fish 3577

LeRobot 入门教程(四)SO-101机械臂组装教程

《SO-101机器人组装与配置指南》详细介绍了旗舰机器人SO-101的完整搭建流程。从获取3D打印零件、安装LeRobot软件和FeetechSDK,到分步组装6个关节的机械臂结构(含夹爪/手柄选项),指南提供了清晰的螺丝规格和安装位置说明。重点包括:电机ID/波特率设置方法、USB端口识别技巧、领导者/跟随者臂的校准流程,以及故障排查建议。完成组装后,用户可通过配套Python脚本校准机器人,为后续的自主学习任务做好准备。文档附有视频演示和技术支持通道,确保用户顺利完成机器人部署。

2506_90492529的博客 2527

Tensorflow使用CPU, 不用GUP

tensorflow是否使用GPU问题,训练速度缓慢的情况检查原因,以及如何检查显存。

m0_64748541的博客 1608

关于Ubuntu18.04谷歌浏览器经常卡死的解决

老电脑本来用的是Win系列,后来改成Linux后就不卡了,这几天同Notebook运行的Script开始复杂了,Ubuntu经常卡死(发公众号也经常卡死),本来以为是Ubuntu的问题 后来一想,不对啊,怎么永远都是谷歌浏览器卡死,其他的怎么不卡死呢?然后今天卡死的时候发现其实Ubuntu还是可以直接执行命令的,只是画面卡了而已 后来网上查了查,发现大家也经常遇到这个问题,其实就是谷...

LP890127的博客 1277

【SHP文件-2022.07】吉林省行政区划(省、市、县)+道路网+公路网

吉林省行政区划边界,省级、地市级、区县级,以及道路网和铁路网shp文件,可用于GIS分析

例说局部性原理给程序带来的提升

当然属于,prev_folio是上一次访问的folio,如果运气好,肯定还在cache里,就可以很迅速地访问到。简单解释一下函数的逻辑,pofs是一个数组,数组长pofs->nr_entries,这个数组是由gup接口,通过页表,按PAGE_SIZE的步长,获取到的由用户传入的一个虚拟地址范围里对应的page/folio,函数collect_longterm_unpinnable_folios的目的就是筛选出这个数组里的page/folio是否属于“longterm_unpinnable”。

kaka__55的博客 1341

Acronis Backup Advanced(服务器备份工具)注册版 V11.7.50088

Acronis Backup Advanced 专为大型企业环境设计,为环境中的所有系统提供世界级的保护和快速灵活的灾难恢复,而无论该环境的复杂性;支持:异机还原、集中式管理、业务应用程序保护、多重备份目标、云备份等;仅支持Windows Server服务器系统安装,支持列表:Windows Server 2003--Windows Server 2016

上一篇: vmap; kmap ; remap_vmalloc_range ; remap_pfn_range
下一篇: linux kernel-4.9 PageActive PageLRU等定义
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值