前提・実現したいこと
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がハングアップしたときのログは何も記録されていませんでした。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/10/13 08:37