커널모듈을 테스트하는 중에는 많은 printk를 사용하게 된다. 또한 모듈이 제어하는 디바이스에 이상이 생길 때
동일한 많는 수의 (커널)메시지를 발생하게 되어 운영체제에 좋지 않는 영향을 미치는 경우가 서버운영중에 종종 나타나게 된다.
이러한 경우에 대비하기 위해 모듈프로그래머가 할 수 있는 일은 불필요한 많는 수의 printk를 생산해 내지 않는 것이다.


이러한 일을 돕기 위해 linux커널에서 제공하는 것이 printk_ratelimit()라는 커널API이다.
이것은 간단히 말하면, 현 시점에서 최근(msec)에 printk가 호출되었는지 아닌지를 판별하는 함수이다.
함수와 함께 전달해야 할 파라메터는 없으며, 다음과 같이 사용할 수 있다.


for (i=0; i<100; i++) {
   if (printk_reatlimit()) {
       printk("kernel message-%d\n", i);
   }
}


그러면, 얼마만큼의 printk를 허용할 것인가를 정해야 할 것이다. 또한 printk()가 영원히 차단되면 당연히 안 되기 때문에
 어느 정도의 시간이 지나면 printk()를 다시 허용할 것인지를 정해야 할 것이다. 이러한 기능을 하는 것인 바로 /proc/sys/kernel밑에
 다음 2개의 파일이다.


 1) printk_ratelimit_burst: 한꺼번에 허용되는 printk호출 횟수, 'struct ratelimit_state'의 burst필드값
 2) printk_ratelimit: 차단된 후 다시 허용되기 까지의 시간간격(초), 'struct ratelimit_state'의 interval필드값


이 함수 printk_ratelimit()와 관련되어 있는 ___ratelimt()를 살펴보자.


   int ___ratelimit(struct ratelimit_state *rs, const char *func);


rs는 interval과 burst값을 가지고 있는 구조체이다. func는 함수 printk_ratelimit()를 호출한 곳에 해당하는 함수이름이다.
커널의 jiffies값이 rs->begin으로부터 rs->interval사이에 있다면  printk는 차단된다.
현재 시각(jiffies)이 rs에 지정된 시간간격을 지나면(begin,interval) printk를 다시 허용된다.


int ___ratelimit(struct ratelimit_state *rs, const char *func) {
  .....
  if (time_is_before_jiffies(rs->begin + rs->interval)) { // printk금지를 해제
     // # of missed-messages 리포팅
     printk(KERN_WARNING "%s: %d callbacks suppressed\n", func, rs->missed);
     // rs구조체를 초기화
     rs->begin   = 0;
     rs->printed = 0;
     rs->missed  = 0;
     return true;
  }

  if (rs->burst > rs->printed) { // printk수가 burst값보다 작다면 ...
     rs->printed++; // 현재까지 누적된 printk수가 rs->printed에 저장되어 있다.
     ret = true; // printk호출가능
  } else {
     // printk호출가능하지 않음
     rs->missed++; // printk를 호출한다면, 메시지 miss될 것임을 의미함
     ret = false;
  }
  .....

  return ret;

}


결론적으로 printk_ratelimit()를 사용한다면,  시간간격(interval)내에서의 printk호출을 burst개로 제한시킬 수 있다.