동적 메모리 할당

Jeong Kwanhee의 이미지

다름이 아니라, 동적 메모리 할당을 위해 kmalloc을 수행한 후, 정해진 메모리 사이즈보다 더 큰 메모리가 필요할 때마다 krealloc을 통해 추가로 할당해주고 있습니다.

예를 들어,

info = (struct context_info *)kmalloc(_BUFSIZE * sizeof(struct context_info), GFP_KERNEL);

if(context_switched_current >= (alloc_cnt * _BUFSIZE)) {

tmp_info = (struct context_info *)krealloc(info, (alloc_cnt + 1) * _BUFSIZE * sizeof(struct context_info), GFP_KERNEL);

if (!tmp_info) {

kfree(info);

return -ENOMEM;

}

info = tmp_info;
alloc_cnt++;
}

해당 코드를 수행할 때, 다음과 같은 문제점이 있었습니다.

"Unable to handle kernel paging request at virtual address"

처음에 _BUFSIZE를 작게 해서 재할당을 자주하게되면 발생하는 듯 싶습니다.

코드자체에 문제가 있는건지? 아니면, 원래 너무 많은 재할당을 하는건 안좋아서 발생하는건지?

pastime의 이미지

메시지를 보면 커널 주소 공간에서 page fault가 발생한 것 같습니다.

kmalloc으로 할당한 메모리(페이지)는 항상 RAM에 존재할텐데
혹시 해당 함수의 리턴값을 체크하지 않았거나
할당된 영역을 넘어서는 주소를 참조한 것은 아닌지요?

headbang의 이미지

커널 모드에서 접근하는 가상 주소가 잘 못된 경우입니다.

의심이 되는 상황은 다음과 같습니다.

1. krealloc()이 실패
2. kfree(info) 수행
3. 다른 곳에서 추가적인 kmalloc() 등이 발생해서 kfree(info)가 해제한 공간 할당
4. 기존 포인터 info 를 통해 계속해서 주소 접근

그나저나 PC는 아닌것 같은데 타겟 프로세서는 무엇인가요?

Jeong Kwanhee의 이미지

1. krealloc()이 실패
>실패했을 때, 루틴을 통과하지 않습니다.
2. kfree(info) 수행
>이부분은 의심이 되어 빼고 마지막에 kfree(info)를 하였습니다.
3. 다른 곳에서 추가적인 kmalloc() 등이 발생해서 kfree(info)가 해제한 공간 할당
>해제된 공간을 할당하면 문제가 생기나요???
이 점 자세한 설명 부탁드립니다....
4. 기존 포인터 info 를 통해 계속해서 주소 접근
> info = tmp_info; 형태로 하여서 접근하므로 문제가 없는것으로 보입니다.

headbang의 이미지

위에 분이 말씀하신것 처럼 호출자가 해당 함수의 리턴값을 검사하지 않고 info 값을 접근했을 때의 문제점을 풀어 쓴 것입니다.

>해제된 공간을 할당하면 문제가 생기나요??? 이 점 자세한 설명 부탁드립니다....
--> kfree(info)로 해제된 공간은 다음에 ptr = kmalloc() 등이 불리면 다시 할당이 되겠지요.
그러면 같은 공간을 info와 ptr 둘을 이용해서 접근할 수 있다는 의미였습니다.
해당 함수의 리턴값을 검사하셨다면 문제 될 게 없을 듯 합니다.

근데 가능하다면 할당방법을 바꾸는게 좋을 듯 합니다.
kmalloc(), krealloc() 은 물리주소공간상에 연속적인 메모리를 요구하기 때문에 메모리 단편화가 진행되면 큰 메모리 할당은 실패할 가능성이 높습니다.

아래처럼 info를 배열로 잡고 하나씩 잡는게 어떨까요?
info[i] = (struct context_info *)kmalloc(sizeof(struct context_info), GFP_KERNEL);

kmalloc() 대신에 아래 함수를 쓰면 메모리를 좀 더 효율적으로 쓸 수 있습니다.
kmem_cache_create(), kmem_cache_alloc(), kmem_cache_free()

어쩔 수 없이 통으로 메모리를 할당해야 한다면 kmalloc(), krealloc() 대신 vmalloc()을 쓰면 메모리 할당이 실패할 확률이 줄어듭니다.
vmalloc()이 반환하는 메모리는 물리주소공간상에 연속적일 필요없이 가상주소공간상만 연속적이면 되니까요.

Jeong Kwanhee의 이미지

아래처럼 info를 배열로 잡고 하나씩 잡는게 어떨까요?
info[i] = (struct context_info *)kmalloc(sizeof(struct context_info), GFP_KERNEL);
-> kmalloc을 수행한 후, 받은 포인터변수 info를 이용해서 접근하기 때문에 배열로 잡게 되면 어려움이 생기네요.

kmalloc() 대신에 아래 함수를 쓰면 메모리를 좀 더 효율적으로 쓸 수 있습니다.
kmem_cache_create(), kmem_cache_alloc(), kmem_cache_free()
-> 이부분은 생각해봐야겠구요.

어쩔 수 없이 통으로 메모리를 할당해야 한다면 kmalloc(), krealloc() 대신 vmalloc()을 쓰면 메모리 할당이 실패할 확률이 줄어듭니다.
vmalloc()이 반환하는 메모리는 물리주소공간상에 연속적일 필요없이 가상주소공간상만 연속적이면 되니까요.
-> 현재 vmalloc으로 바꾸고 재할당할 때, memset을 이용해 copy하고 있습니다. 처음 메모리를 크게 잡아서 재할당을 거의 없게 만들면, 자주 해당 func을 수행해도 문제가 발생하지 않습니다. 하지만, 아주 작은 메모리를 잡고 잦은 재할당을 하게 되면, 같은 문제가 발생하네요...이건 재할당을 자주해서 생기는 문제라고 볼수도 있는건지 궁금합니다. free를 하는데 바로 수행하지 않고 메모리 반납을 하는데 시간이 걸리는 것 같아서요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.