不思議な行動のprintk linuxカーネルモジュール
-
29-09-2019 - |
質問
皆様にお伝えしたくて書き込みコードのためのlinuxカーネルモジュールを体験する不思議な行動します。こちらは自分のコード:
int data = 0;
void threadfn1()
{
int j;
for( j = 0; j < 10; j++ )
printk(KERN_INFO "I AM THREAD 1 %d\n",j);
data++;
}
void threadfn2()
{
int j;
for( j = 0; j < 10; j++ )
printk(KERN_INFO "I AM THREAD 2 %d\n",j);
data++;
}
static int __init abc_init(void)
{
struct task_struct *t1 = kthread_run(threadfn1, NULL, "thread1");
struct task_struct *t2 = kthread_run(threadfn2, NULL, "thread2");
while( 1 )
{
printk("debug\n"); // runs ok
if( data >= 2 )
{
kthread_stop(t1);
kthread_stop(t2);
break;
}
}
printk(KERN_INFO "HELLO WORLD\n");
}
基本的には思っていたのを待つのスレッドに仕上げとその後の印刷ものである。上記のコードは達が "printk("debug\n");"
なりました。ってすぐにコメントアウト printk("debug\n");
のコードのデバッグおよび負荷のモジュールをinsmodコマンドを実行すると、モジュールの話では少ないので、工夫が必要かと思い迷う再帰.あまりないと思いますかprintk効果を自分のコードに大きなそうです。
の手によりお願い申し上げます。
い申し上げます。
解決
電話があります printk()
削除するコンパイラがループを最適化しています while (1);
. 。通話を追加するとき printk()
コンパイラはそれを確信していません data
変更されていないため、ループを介して毎回値をチェックします。
ループに障壁を挿入すると、コンパイラが再評価されます data
各反復で。例えば:
while (1) {
if (data >= 2) {
kthread_stop(t1);
kthread_stop(t2);
break;
}
barrier();
}
他のヒント
ないとの同期アクセスのデータを可変となります。何が起こるが、そのコンパイラが生まれ、無限ループを実行します。こちらはなぜ:
while( 1 )
{
if( data >= 2 )
{
kthread_stop(t1);
kthread_stop(t2);
break;
}
}
のコンパイラを検出できる値のデータ変わることはありませんの中にループを実行します。そのためで完全にチェックアウトはゆとりのループだと簡単に
while (1) {}
場合に挿入すprintkのコンパイラにすることができるものとし、グローバル変数のデータは変更後のコンパイラはそのprintkは詳細)ではコードの開始を求め、すがろうとする。(a未定義の動作の一種です。)
どうすればいい:
適切なスレッドの同期プリミティブ.まwrapへのアクセスデータコード部で保護されているミューテックスのコードします。このまま置き換え、変数のデータを使用数セマフォです。
編集:
このリンクについて説明ロックのlinuxカーネル作品:
http://www.linuxgrill.com/anonymous/fire/netfilter/kernel-hacking-HOWTO-5.html
多分データは揮発性と宣言する必要がありますか?コンパイラがループ内のデータを取得するためにメモリにならない可能性があります。
Nils Pipenbrinckの答えはスポットです。ポインターを追加するだけです。
カーネルロックに関するRustyの信頼できないガイド (すべてのカーネルハッカーはこれを読む必要があります)。
さようならセマフォ?, Mutex API (lwn.net 2006年初頭に導入された新しいMutex APIに関する記事は、Linuxカーネルがセマフォをミューテックスとして使用していました)。
また、共有データは単純なカウンターであるため、Atomic APIを使用するだけです(基本的に、カウンターをAtomic_tとして宣言し、Atomic_*関数を使用してアクセスできます)。
揮発性は常に「悪い考え」であるとは限りません。揮発性が必要な場合と相互除外メカニズムが必要な場合のケースを分離する必要があります。一方のメカニズムを他のメカニズムに使用または誤用すると、最適ではありません。上記の場合。最適なソリューションのために、両方のメカニズムが必要であることをお勧めします。相互排除を提供するためのミューテックス、「情報」をハードウェアから新鮮に読む必要があることをコンパイラに示すために揮発性を示します。それ以外の場合、一部の状況(最適化-O2、-O3)では、コンパイラは不注意に必要なコードを除外する可能性があります。