我只读了两篇关于这个主题的文章,它提供了不一致的信息,所以我想知道哪一个是正确的.也许两者都是正确的,但在什么情况下呢?
在第一个,我们取一个状态页面大小时间
高速缓存控制器始终观察正在加载的存储器位置,并在刚刚读取的存储器位置之后从几个存储器位置加载数据.
为了给你一个真实的例子,如果CPU加载的数据存储在地址1,000中,缓存控制器将从地址1,000之后的"n"地址加载数据.这个数字"n"叫做页面; 如果给定的处理器使用4 KB页面(这是一个典型值),它将从正在加载的当前内存位置以下的4,096个地址加载数据(在我们的示例中为地址1,000).在下图中,我们举例说明了这个例子.

在第二个状态之一,我们获取的sizeof(高速缓存行)+的sizeof(预取)时间
因此,我们可以总结内存缓存的工作原理:
- CPU请求存储在地址"a"中的指令/数据.
- 由于地址"a"的内容不在内存缓存中,因此CPU必须直接从RAM中获取它.
- 高速缓存控制器从地址"a"开始将一行(通常为64字节)加载到存储器高速缓存中.这是比CPU请求的数据更多的数据,因此如果程序继续按顺序运行(即询问地址a + 1),CPU将要求的下一条指令/数据将已加载到内存高速缓存中.
- 一个名为prefetcher的电路加载位于该行之后的更多数据,即开始将地址a + 64中的内容加载到缓存中.为了给你一个真实的例子,Pentium 4 CPU有一个256字节的预取器,所以它在已经加载到缓存中的行之后加载接下来的256个字节.
假设我们struct page从页面缓存文件的地址空间获得了一个.
我们如何从中获取4KB数据的起始物理地址struct page?
我想应该有像data指针里面的东西struct sk_buff,但我没有找到它.
编辑
感谢Mat和llya的答案.
在查看答案后,我认为第一个问题是确定它是否struct page位于ZONE_NORMAL或ZONE_HIGHMEM.
在文件I/O期间,当我们找不到缓存页面时,我们将首先使用分配新页面page_cache_alloc_cold().page_cache_alloc_cold()将最终调用alloc_pages()看起来它将使用ZONE_HIGHMEM(在x86中,是从PAGE_OFFSET+ 896M 开始的内核内存区域)来完成它的工作.
所以
ZONE_NORMALkmap()用来查找与struct页面关联的4KB数据的起始物理地址,我们应该用它(unsigned long)(&page)-PAGE_OFFSET来查找存储结构本身的物理地址吗?请改正.
我刚读了一篇解释零拷贝机制的文章.
它讨论了有和没有Scatter/Gather支持的零拷贝之间的区别.
网卡没有SG支持,数据副本如下

NIC支持SG,数据副本如下

总之,使用SG支持的零拷贝可以消除一个CPU拷贝.
我的问题是为什么内核缓冲区中的数据可能会分散?
我是 linux 内核的新手。最近,我经历了内核 2.6.33 中的 sendfile 系统调用。以下是我的行程顺序:
do_sendfile()
=> do_splice_direct()
=> splice_direct_to_actor()
=> do_splice_to()
=> do_splice_from()
=> splice_read,splice_write
Run Code Online (Sandbox Code Playgroud)
在整个序列中,我没有找到 splice 使用 DMA 副本的地方。那么DMA复制在哪里发生呢?
在task_struct中,我们可以找到:
struct mm_struct *mm, *active_mm;
struct files_struct *files;
Run Code Online (Sandbox Code Playgroud)
files_struct包含指向最多256个文件数据结构的指针,每个文件数据结构描述此进程正在使用的文件.
struct file * fd_array[NR_OPEN_DEFAULT];
Run Code Online (Sandbox Code Playgroud)
mm_struct包含vm_area_struct.
struct vm_area_struct * mmap; /* list of VMAs */
Run Code Online (Sandbox Code Playgroud)
在vm_area_struct中,我们可以找到:
struct file * vm_file; /* File we map to (can be NULL). */
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:
fd_array和vm_file中的文件之间有什么关系?
fd_array中显示的所有文件是否也将以与图片中所示类似的方式映射到vm_area_struct中?或者,vm_area_struct中映射的所有文件是否都会显示在fd_array中?
谢谢,
一只忙碌的猫http://static.duartes.org/img/blogPosts/memoryDescriptorAndMemoryAreas.png
~$dmesg | grep tty
[ 0.000000] console [tty0] enabled
[ 15.905810] usb 3-3: pl2303 converter now attached to ttyUSB0
[ 3910.549952] pl2303 ttyUSB0: pl2303 converter now disconnected from ttyUSB0
[ 3929.763287] usb 3-3: pl2303 converter now attached to ttyUSB0
~$lsusb
Bus 003 Device 002: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
Minicom configuration
| A - Serial Device : /dev/ttyUSB0 |
| B - Lockfile Location : /var/lock |
| C - Callin Program : |
| D - …Run Code Online (Sandbox Code Playgroud) 假设CPU修改了位置x+50中的值并且没有将其刷新回主存(回写)。
同时,设备发起从 x 到 x+100 的 DMA 读取请求。
那么,如何通知CPU刷新脏缓存行呢?
当我试图定义一些局部范围属性时,我发现用'@'定义的属性不能直接在链接函数中访问,而对于那些用'='或'&'定义的属性不是这种情况.
这是我写的简单指令(jsfiddle):
angular.module('test', [])
.controller('testCtrl', function($scope) {
$scope.count1 = 5;
})
.directive('testDir', function() {
return {
restrict: 'A',
scope: {
count: '=',
readonly: '@'
},
link: function (scope, elem, attrs) {
console.log('Outside has count? '+('count' in scope));
console.log('Outside has readonly? '+('readonly' in scope));
scope.$watch('count', function(value){
console.log('Inside has count? '+('count' in scope));
console.log('Inside has readonly? '+('readonly' in scope));
elem.text(value);
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
输出是:
外面有'数'?真正
外面有"只读"吗?假
里面有'数'?真正
里面有"只读"吗?真正
我不知道为什么scope.readonly(@)没有在范围之外定义.$ watch函数虽然不是scope.count(=)的情况?
我刚看了一篇文章说:
控制中断系统的原因通常归结为需要提供同步.通过禁用中断,可以保证中断处理程序不会抢占当前代码.此外,禁用中断还会禁用内核抢占.但是,禁用中断传送和禁用内核抢占都不能提供对来自另一个处理器的并发访问的任何保护.
所以我只是想知道中断和内核抢占之间的区别.
或者我们可以说禁用内核抢占还会禁用中断吗?
我试图了解如何在Linux内核版本2.6.33中实现TCP三次握手.
我从函数accept()开始,它引导我:
接受()==> sys_accept()==> sys_accept4()==> inet_accept()==> inet_csk_accept()
现在我被困在inet_csk_accept()中.
struct sock *inet_csk_accept(struct sock *sk, int flags, int *err)
{
struct inet_connection_sock *icsk = inet_csk(sk);
struct sock *newsk;
int error;
lock_sock(sk);
/* We need to make sure that this socket is listening,
* and that it has something pending.
*/
error = -EINVAL;
if (sk->sk_state != TCP_LISTEN)
goto out_err;
/* Find already established connection */
if (reqsk_queue_empty(&icsk->icsk_accept_queue)) {
long timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
/* If this is a non blocking …Run Code Online (Sandbox Code Playgroud) 我只写了一个简单的程序来打印变量的地址.
#include <stdio.h>
void main(){
int *a;
int b;
b=5;
a=&b;
printf("\n*a is the value of the integer: %d\n",*a);
printf("&a is the address of variable a: %p\n", &a);
printf(" a is the address stored in a: %p\n",a);
printf("&b is the address of variable b: %p\n\n",&b);
}
Run Code Online (Sandbox Code Playgroud)
结果是:
*a is the value of the integer: 5
&a is the address of variable a: 0x7fff935ad2b0
a is the address stored in a: 0x7fff935ad2bc
&b is the address of variable b: 0x7fff935ad2bc
Run Code Online (Sandbox Code Playgroud)
为什么打印的地址不是标准格式? …