我的站点

一个系统软件工程师的随手涂鸦

Date: 八月 11, 2015

Linux kernel IOMMU代码分析笔记(9)——EIM,IR和QI

支持IOMMU的硬件单元的Extended Capability Register有三个关联的位:

EIMExtended Interrupt Mode):在X86_64平台,0表示支持xAPIC1表示支持x2APICItanium平台这一位没意义。并且这一位只有在IR位设置为1才有效。

IRInterrupt Remapping support):1表示支持Interrupt remapping0表示不支持。硬件单元支持Interrupt remapping,也必须支持QI

QIQueued Invalidation support):1支持Queued Invalidation0表示不支持。

参考资料:
Intel ® Virtualization Technology for Directed I/O

git小技巧(6)——“git branch -m

git branch -m <oldname> <newname>可以把branch重命名。例如:

[root@localhost test_git]# git branch
  master
* new
[root@localhost test_git]# git branch -m new new1
[root@localhost test_git]# git branch
  master
* new1

如果要重命名的就是当前branch,可以省略<oldname>

[root@localhost test_git]# git branch -m new2
[root@localhost test_git]# git branch
  master
* new2

Linux kernel IOMMU代码分析笔记(8)——intel_enable_irq_remapping(2)

上文

(4)

for_each_iommu(iommu, drhd) {
    /*
     * If the queued invalidation is already initialized,
     * shouldn't disable it.
     */
    if (iommu->qi)
        continue;

    /*
     * Clear previous faults.
     */
    dmar_fault(-1, iommu);

    /*
     * Disable intr remapping and queued invalidation, if already
     * enabled prior to OS handover.
     */
    iommu_disable_irq_remapping(iommu);

    dmar_disable_qi(iommu);
}

上面代码含义是如果硬件单元的queued invalidation还没有初始化,则清掉之前的fault,并且disable IRQ remappingqueued invalidation

(5)

/*
 * check for the Interrupt-remapping support
 */
for_each_iommu(iommu, drhd) {
    if (!ecap_ir_support(iommu->ecap))
        continue;

    if (eim && !ecap_eim_support(iommu->ecap)) {
        printk(KERN_INFO "DRHD %Lx: EIM not supported by DRHD, "
               " ecap %Lx\n", drhd->reg_base_addr, iommu->ecap);
        goto error;
    }
}

上述代码含义是如果硬件支持IRQ remapping并且系统支持x2APIC模式,如果硬件不支持x2APIC模式,就失败。

(6)

/*
 * Enable queued invalidation for all the DRHD's.
 */
for_each_iommu(iommu, drhd) {
    int ret = dmar_enable_qi(iommu);

    if (ret) {
        printk(KERN_ERR "DRHD %Lx: failed to enable queued, "
               " invalidation, ecap %Lx, ret %d\n",
               drhd->reg_base_addr, iommu->ecap, ret);
        goto error;
    }
}

/*
 * Setup Interrupt-remapping for all the DRHD's now.
 */
for_each_iommu(iommu, drhd) {
    if (!ecap_ir_support(iommu->ecap))
        continue;

    if (intel_setup_irq_remapping(iommu, eim))
        goto error;

    setup = 1;
}

if (!setup)
    goto error;

上述代码分别为每个硬件单元enable queued invalidationIRQ remapping

(7)

irq_remapping_enabled = 1;

/*
 * VT-d has a different layout for IO-APIC entries when
 * interrupt remapping is enabled. So it needs a special routine
 * to print IO-APIC entries for debugging purposes too.
 */
x86_io_apic_ops.print_entries = intel_ir_io_apic_print_entries;

pr_info("Enabled IRQ remapping in %s mode\n", eim ? "x2apic" : "xapic");

return eim ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE;

error:
    /*
     * handle error condition gracefully here!
     */

if (x2apic_present)
    pr_warn("Failed to enable irq remapping.  You are vulnerable to irq-injection attacks.\n");

return -1;

如果成功的话,返回IRQ_REMAP_XAPIC_MODE(0)IRQ_REMAP_X2APIC_MODE(1),否则返回-1

参考资料:
"BIOS Considerations" in *Intel ® Virtualization Technology for Directed I/O

git reset简介

git reset把当前branchHEAD恢复到之前某个snapshot。举例如下:

假设当前repository分三次添加abc文件:

[root@localhost test_git]# git log --oneline
e5b4692 Add c
be89e2d Add b
80c615e Add a

执行git reset --hard HEAD~1命令,HEAD~1表示当前HEAD之前的第一个commit

[root@localhost test_git]# git reset --hard HEAD~1
HEAD is now at be89e2d Add b
[root@localhost test_git]# git status
On branch master
nothing to commit, working directory clean
[root@localhost test_git]# git log --oneline
be89e2d Add b
80c615e Add a
[root@localhost test_git]# ls
a  b

可以看到git log中已经找不到添加c文件的log。而c文件也不存在了。

如果执行git reset --mixed HEAD~1命令,则虽然repository已经回滚到HEAD之前的第一个commit,但c文件还会存在:

[root@localhost test_git]# git reset --mixed HEAD~1
[root@localhost test_git]# git log --oneline
be89e2d Add b
80c615e Add a
[root@localhost test_git]# ls
a  b  c

恢复之前HEAD状态,可以利用git reflog找到相应的commit,然后创建一个新的branch,最后mergemaster:

[root@localhost test_git]# git reflog
be89e2d HEAD@{0}: reset: moving to HEAD~1
deb862b HEAD@{1}: commit: Add c
be89e2d HEAD@{2}: reset: moving to HEAD~1
e5b4692 HEAD@{3}: commit: Add c
be89e2d HEAD@{4}: commit: Add b
80c615e HEAD@{5}: commit (initial): Add a
[root@localhost test_git]# git checkout deb862b
Note: checking out 'deb862b'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at deb862b... Add c
[root@localhost test_git]# git log --oneline
deb862b Add c
be89e2d Add b
80c615e Add a
[root@localhost test_git]# git branch
* (HEAD detached at deb862b)
  master
[root@localhost test_git]# git checkout -b temp
Switched to a new branch 'temp'
[root@localhost test_git]# git branch
  master
* temp
[root@localhost test_git]# git checkout master
Switched to branch 'master'
[root@localhost test_git]# git merge temp
Updating be89e2d..deb862b
Fast-forward
 c | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 c
 [root@localhost test_git]# ls
a  b  c

git小技巧(5)——“git checkout -b

git checkout -b <branch>"创建一个新的branch,并且切换到这个branch上。例如:

[root@localhost git_repo]# git checkout -b new-branch
Switched to a new branch 'new-branch'
[root@localhost git_repo]# git branch
  master
* new-branch

Go语言实践技巧(5)——defer

defer语句使用例子如下:

file, err := os.Open(dataFile)
if err != nil {
    ...
}
defer file.Close()

defer语句可以看成是把指定的函数压入“堆栈”,当外面函数退出时(即使发生panic),“堆栈”内的函数会依次弹出执行。这样可以防止资源泄露。

Go语言实践技巧(4)——goroutine之间切换的时间点

以下列出了goroutine之间切换的主要的时间点:

(1)Channel发送和接收操作(如果这些操作是阻塞的);
(2)执行go语句,虽然不能保证新的goroutine马上被调度执行;
(3)阻塞的系统调用,像文件操作,网络操作等等;
(4)停下来进入垃圾回收周期以后。

换句话讲,在goroutine不能继续进行运算以后(需要更多数据,更多空间,等等),都会进行切换。

参考资料:
Performance without the event loop

Powered by WordPress & Theme by Anders Norén