質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Q&A

2回答

1315閲覧

カーネル空間でユーザー空間で確保したメモリを直接参照

haggy

総合スコア8

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

0グッド

3クリップ

投稿2020/10/12 07:48

前提・実現したいこと

Snapdragon410搭載のボード上でLinaro Debian(Linux kernel 4.14.0ベース)を動かしています。
自作のアプリケーションを動かしているとOSがハングアップしてしまう現象が起きました。(早いと1日、遅いと14日、1カ月以上動かしても発生しないことも。)
ボード上にI2Cデバイスがのっており、そのドライバを自作していましたが、それに問題を見つけました。
/devにデバイスファイルを作成し、それをopenしてread/writeをコールするようなドライバです。(アプリの中からコールしています。)
そのwriteの実装を以下のようにしていました。

C

1static ssize_t mydevice_write(struct file *fp, const char __user *buf, size_t count, loff_t *f_pos) 2{ 3 s32 ret; 4 5 ret = i2c_smbus_write_byte_data(i2c_client, buf[0], buf[1]); 6 if(ret < 0) { 7 return ret; 8 } 9 10 return count; 11}

ユーザー空間で確保したメモリbufを直接参照していました。
copy_from_userを使うべきであり、以下のように修正しました。

C

1static ssize_t mydevice_write(struct file *fp, const char __user *buf, size_t count, loff_t *f_pos) 2{ 3 s32 ret; 4 char wdata[2] = {0}; 5 6 if (count > 2) { 7 return -EINVAL; 8 } 9 10 if (copy_from_user(wdata, buf, count)) { 11 return -EFAULT; 12 } 13 14 ret = i2c_smbus_write_byte_data(i2c_client, wdata[0], wdata[1]); 15 if(ret < 0) { 16 return ret; 17 } 18 19 return count; 20}

修正版のドライバで動かしていますが、今のところOSがハングアップしてしまう現象は起こってないです。
しかし、本当にこれが原因だったのか自信が無いという状況です。
調べた限りでは、ユーザー空間で確保したメモリがスワップされ、RAM上に無いときに参照しようとするとエラーが起きるということでした。
しかし、動作環境ではスワップ領域を作成していないため、スワップは起きません。
実際にこの問題が起きる直前までvmstatで監視していましたが、スワップは起きていませんでした。

私が調べた以外の条件でもエラーが起きることは考えられるのでしょうか?

発生している問題・エラーメッセージ

/var/log/を確認しましたがOSがハングアップしたときのログは何も記録されていませんでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

systemcall や libraly って、
その為に有るんじゃなかったでしたっけ?

あと、
>>動作環境ではスワップ領域を作成していないため、スワップは起きません。
>>実際にこの問題が起きる直前・・スワップは起きていませんでした。

領域が無いのでスワップは起きないのは当たり前で、
領域が有っても、スワップしない様にチューニングするべきであり、
本末転倒もいいところです。

投稿2020/10/12 12:44

hana_yama_san

総合スコア923

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

haggy

2020/10/13 08:37

回答ありがとうございます。 >systemcall や libraly って、 >その為に有るんじゃなかったでしたっけ? これはどういう意味でしょうか。
guest

0

※OSの一般論で書いています。
あるユーザー空間内に確保したメモリを他のユーザー空間から使用しようとした場合、実アドレスでのアクセスならば動くかもしれませんが、仮想アドレスならば全く別の実アドレスにアクセスすることになります。
(ユーザー空間の仮想アドレスに対応する実アドレスは、ユーザー空間毎に必ず違う実アドレスになっているため)
そのため、ドライバーが動作するのが最初にメモリを確保したユーザー空間の場合は正常に動作するでしょうが、他のユーザー空間で動作している場合には想定外の動作をすることになります。
そのドライバーが動作する空間が固定されていない限り、不定期にエラーが発生します。

投稿2020/10/12 12:30

sage

総合スコア1216

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sage

2020/10/12 12:40

I/O装置のドライバーならば、I/O割込みの延長で動作するでしょうから、その時にどのアドレス空間で動作しているかは不定だと思います。
haggy

2020/10/13 08:33

回答ありがとうございます。 >そのため、ドライバーが動作するのが最初にメモリを確保したユーザー空間の場合は正常に動作するで>しょうが、他のユーザー空間で動作している場合には想定外の動作をすることになります。 >そのドライバーが動作する空間が固定されていない限り、不定期にエラーが発生します。 ドライバが動作するのはカーネル空間ではないのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問