Tag Archives: Linux

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. 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