SPIN_LOCK 小註解

最近看到一個 Kernel config 叫做 CONFIG_UNINLINE_SPIN_UNLOCK, 這 un 又 un, 真的是讓人看得眼花. 雖然說現在人強調 “減法" 的思維, 看這個名詞還是得用 “加法".

STEP 1: SPIN_LOCK [1], 多處理器共用一個資源時, 透過 SPIN_LOCK 去鎖住不讓其他人用. 自己用完後, 設為 unlock, 別人就可以用. 怎麼知道可不可以用呢? 要透過 trylock() 來判斷是否拿到資源. 如果拿不到回直接回傳 busy, 除非一直 try 否則也不會浪費資源. 真的 try 不停就要看演算了 [2].

STEP 2: INLINE_SPIN_LOCK. inline 是指會將 spin_lock() 插入程式之中. 但它也不只是當作巨集處理而已, 參考 [3] 這段話, 它會把 spin_lock() 這個函式的內容優化之後才代入. 

The point of making a function inline is to hint to the compiler that it is worth making some form of extra effort to call the function faster than it would otherwise – generally by substituting the code of the function into its caller. As well as eliminating the need for a call and return sequence, it might allow the compiler to perform certain optimizations between the bodies of both functions.

STEP 3:  INLINE_SPIN_UNLOCK. 有鎖的動作就有解鎖. 使用之前, kernel config 要先打開. 追溯到 2012 年, 當初只有 CONFIG_INLINE_SPIN_UNLOCK [4].

STEP 4:  Linus Torvalds 自己建議把原本預設開 CONFIG_INLINE_SPIN_UNLOCK, 改為預設 CONFIG_UNINLINE_SPIN_UNLOCK 未定義 [4].

-CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_UNINLINE_SPIN_UNLOCK is not set

想要 debug inline spin unlock 的人如果想要加 debug code, 開這個 config 就不會因為 inline 的作用, 使自己的 code 和原本 inline 的函式融為一體, 以致於無法正確地 debug.

預期的路人心得:  不能因為負負得正, 就把 CONFIG_UNINLINE_SPIN_UNLOCK 想成 CONFIG_INLINE_SPIN_LOCK. 哈!

[Ref]

  1. https://blog.csdn.net/u010144805/article/details/80354679
  2. https://locklessinc.com/articles/locks/
  3. http://www.greenend.org.uk/rjk/tech/inline.html
  4. http://lkml.iu.edu/hypermail/linux/kernel/1203.2/03015.html

foreign-architecture 小註解

今天想要用 apt-get, 結果冒出 Unable to locate package git-fame

cashchou@server: ~ $ sudo apt-get install git-fame
Reading package lists… Done
Building dependency tree
Reading state information… Done
E: Unable to locate package git-fame

為了消除  Unable to locate package, 據說要清理 source list, 很多人是因為網路的關係連不上 ubuntu, 但我確定都連得上, 所以不用改 source list. 而是可以試著 update. 結果在 apt-get update 的時候, 看到一堆類似的 warning. 像是:

W: Failed to fetch http://tw.archive.ubuntu.com/ubuntu/dists/precise-updates/InRelease Unable to find expected entry ‘ main/binary-foreign-architecture/Packages’ in Release file (Wrong sources.list entry or malformed file)

之類的東西. 話說 main 和 Packages 中間應該是出現 architecture 沒錯, 但應該是 amd64, i386 這種 architecture, 而不是直接來個 foreign architecture 吧! 

cashchou@server: /etc/apt $ dpkg –print-architecture
amd64
cashchou@server: /etc/apt $ dpkg –print-foreign-architectures
foreign-architecture

這表示我們 server 的架構是 amd64, 如果曾不小心打成 and64, 或是 i586 打成 1586…這些都會被認為是不相容的外國建築 (foreign-architectures) . 但…這 server 上的外國建築竟然就叫做外國建築吶! 我試著把它刪除, 結果…得到一句繞口令…不能移除不是外國建築的外國建築.

cashchou@server: /etc/apt $ dpkg –remove-architecture foreign-architectures
dpkg: warning: cannot remove non-foreign architecture ‘foreign-architectures’

原來是我忘了 sudo, 加 sudo 硬是把它幹掉之後, apt-get update 就正常了.

sudo dpkg –remove-architecture foreign-architecture

但還是不能 upgrade.

cashchou@server: /etc/apt $ sudo apt-get upgrade
Reading package lists… Done
Building dependency tree
Reading state information… Done
You might want to run ‘apt-get -f install’ to correct these.
The following packages have unmet dependencies: …一大堆錯誤

據說, 此時可以試著 apt-get -f install, 但我試過這招沒用. 因為 unmet 太多了.

…一大堆錯誤
E: Unmet dependencies. Try using -f.

啊 force 也沒用啊!! 根據網路資訊 [1], 接下來的 SOP 就是先自動修復, 依序執行下面幾步. 當然 // 後面不是指令, 只是註解.

sudo apt-get update      // update your package list
sudo apt-get autoclean   // clean up any partial packages
sudo apt-get clean       // clean up the apt cache
sudo apt-get autoremove  // will clean up any unneeded dependencies.

還不行的話, 只好逐個修復. 

sudo dpkg --remove -force --force-remove-reinstreq package name

弟兄們裝了太多 package, 彼此互相影響, 我沒時間一個一個重裝, 只好留待比較急的人有緣人來處理了~~~

[REF]

  1. http://www.linuxquestions.org/questions/linux-general-1/resolve-generated-breaks-held-packages-896449/

POSIX signal 小整理

做 SOC 軟體的人常常會收到 bug 的 log, 其中一個常見的類型就是 signal XXX, code YYY, fault address ZZZ. 例如:

Fatal signal 11 (SIGSEGV), code 2, fault addr 0x12345678 in tid 12345 (MyTask)

這個 log 是標準 C library 裡面的 signal.h 所定義的 [1].  參考 ref [2], 裡面有較完整的 code No. 說明, 而 ref [3] 有完整的 POSIX signal 定義和歷史沿革; Ref [4] 是把 Unix signal 做成一張表.

取常用的部分, 重新整理如下. 這些都是 core error, 所以會終止程序, 並且產生 core dump.

Signal

No.

Code

No.

Reason

SIGILL

4

ILL_ILLOPC

1

Illegal opcode.

ILL_ILLOPN

2

Illegal operand.

ILL_ILLADR

3

Illegal addressing mode.

ILL_ILLTRP

4

Illegal trap.

ILL_PRVOPC

5

Privileged opcode.

ILL_PRVREG

6

Privileged register.

ILL_COPROC

7

Coprocessor error.

ILL_BADSTK

8

Internal stack error.

SIGFPE

8

FPE_INTDIV

1

Integer divide by zero.

FPE_INTOVF

2

Integer overflow.

FPE_FLTDIV

3

Floating-point divide by zero.

FPE_FLTOVF

4

Floating-point overflow.

FPE_FLTUND

5

Floating-point underflow.

FPE_FLTRES

6

Floating-point inexact result.

FPE_FLTINV

7

Invalid floating-point operation.

FPE_FLTSUB

8

Subscript out of range.

SIGSEGV

11

SEGV_MAPERR

1

Address not mapped to object.

SEGV_ACCERR

2

Invalid permissions for mapped object.

SIGBUS

10

BUS_ADRALN

1

Invalid address alignment.

BUS_ADRERR

2

Nonexistent physical address.

BUS_OBJERR

3

Object-specific hardware error.

SIGTRAP

5

TRAP_BRKPT

1

Process breakpoint.

TRAP_TRACE

2

Process trace trap.

[REF]

  1. https://zh.wikipedia.org/wiki/Signal.h
  2. http://pubs.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html
  3. http://man7.org/linux/man-pages/man7/signal.7.html
  4. http://people.cs.pitt.edu/~alanjawi/cs449/code/shell/UnixSignals.htm

Linux Kernel 審 code 的流程

 GPL 專家 Armijn 介紹 Linux kernel team 給我們認識, 我才知道想把 code 放進 Linux kernel 不是一件容易的事. 這些也可以給一般的 programmer 參考.

他們第一件事就是要求 coding style. 然後是 check list. 相關的說明可以從 Linux 網站找到.

等到這些 code 變漂亮了 (the code is all great and shiny ) , 還要把 code 切成小塊. 因為太多 code 就很難 review. 另一方面, 切成小塊之後就可以分成不同的 patch.

– Fixing a bug
– Fixing a spelling mistake
– A bug fix for the same bug that appeared in several places over the
   kernel.
– A new driver.
– Support for a new SOC or evaluation board.
 
因為 Linux Kernel 是用 Git 維護 (和 SVN 相對), 只要中間爛掉一版, 後面就麻煩了. (If a version of kernel is broken the use of git bisect is made impossible or significantly harder.)
 
如果一個修改涉及整個 system 或是 SOC, 那麼也不用切小了. 此時可以從 kernel 的 MAINTAINERS 檔案找到對應窗口. 例如:
 
SQUASHFS FILE SYSTEM
M:      Phillip Lougher <phillip@lougher.demon.co.uk>
L:      squashfs-devel@lists.sourceforge.net (subscribers-only)
S:      Maintained
F:      Documentation/filesystems/squashfs.txt
F:      fs/squashfs/
 
L 和 M 裡面至少有一個是負責的窗口, M 是負責人, 而 L 是 mail list 的名單. 如果兩者都不存在, 預設窗口就是 linux-kernel@vger.kernel.org. 顯然 W 是網站 (web), S 是 status, F 是文件 (file), 第二個 F 是 folder, 這說明了這份 code 相關的資訊.
 
所以每當想要加一些 code 到 Linux kernel, 其實不需要別人牽線, 只好自己乖乖地按照應有的步驟把 code 準備好寄出就可以了.

Android 與 Linux 的關係

我們的競爭對手紛紛把 Android 列在他們的 feature set 上, 對於跑 Linux Kernel 的本公司, 感覺好像有點落後~~~

但是 Android 是另外一個 OS (Operating System) 嗎? 不是的! 雖然 Google 強力把它包裝成Google 的 OS, 不過它其實是某種的 Linux. 這也就可以解釋 Google 為何又想要搞另外一套 Chrome OS 出來, 因為 Android 畢竟不是 Google 自己養大的孩子, 只是把別家的孩子抱來養, 穿上 Google 家的衣服而已! 既然 Linux 是受 GPL 授權保護的 open source, Google 當然會覺得養自己的孩子比較保險.

那麼 Android 是怎麼做到的呢? 首先, Google 在 Linux 開了一個後門, 把某些核心程式搬到 LInux 的上頭來, 不再受 Linux 的管轄. 在下圖中黃色的這塊就是 Android 的核心, 各位可以看到它建設在 Linux 的基礎上. 這樣大家應該可以瞭解 Android 是如何寄生於 Linux 的架構.

[圖片遺失]

Mr./Ms. Days (MMDays) – 網路, 資訊, 觀察, 生活 這個網站上, 對於 Android 有很多篇相關的好文章, 大家可以參考這裡的介紹.