Éste código esta hecho 100% por mi, no hay rips, ni nada por el estilo...
Por esto le pido a los ripers que tengan consideración y respeto por el esfuerzo
y que si van a tomar este código por lo menos den creditos...

Aca les dejo el código del driver completo más la GUI, también quería aclarar algunos conceptos
y explicaciones.

El mecanismo que use es parte de los IPC, los netlink funcionan con identificador, y son parecidos
a los sockets solamente que en lugar de bindear un puerto bindean un proceso(y no es todo ya que el mecanismo
que usan en muy complejo para explicarlo en un solo post), este queda a la escucha
de transimision de datos, y por medio de cabezeras especiales que probe el kernel es posible establecer
un arribo de datos.
Ademas los netlink fueron creados especialmente para este tipo de tarea, y sin contar que son asincrónicos
y muy optimos...

el primer código es el del driver principal(modo kernel):
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/netlink.h>
#include <net/sock.h>
#include <net/net_namespace.h>

/* si quires debuggear descomenta esta de lo contrario comentala */
#define DEBUG_ANTIFREEZE_DRIVER

/* Necesaria para interactuar con el espacio de usuario y kernel */
#define NETLINK_KERNEL_GROUP 		30

#define REFRIGERATE_PROCESS 		18
#define FREEZE_PROCESS			19
#define KILL_PROCESS			15

#define _KILL_PROCESS			"[KILL_SIGNAL]"
#define _FREEZE_PROCESS			"[FREEZE_SIGNAL]"
#define _REFRIGERATE_PROCESS		"[REFRIGERATE_SIGNAL]"
#define PID_EX				"[PID_EX]"

#define EZOMBIE 			"EXIT_ZOMBIE|"
#define EDEAD				"EXIT_DEAD|"
#define TDEAD				"TASK_DEAD|"
#define TKILL				"TASK_KILLABLE|"
#define TTRACED				"TASK_TRACED|"
#define TSTOP				"TASK_STOPPED|"
#define TWAKEKILL			"TASK_WAKEKILL|"
#define TWAKING				"TASK_WAKING|"
#define TINTRPT				"TASK_INTERRUPTIBLE|"
#define TUNINTERPT			"TASK_UNINTERRUPTIBLE|"
#define TRUNN				"TASK_RUNNING|"
#define TMAX				"TASK_STATE_MAX|"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("NvK");
MODULE_DESCRIPTION("Modulo para controlar y obtener el consumo de procesos, pudiendolos optimizar y evitar posibles latencias");

static struct sock *nl_sk= NULL;
static struct task_struct *ktask;
static struct mm_struct *MMU;
static struct vm_area_struct *VMA;
static struct pid *pid_struct;

struct nlmsghdr *nlh= NULL;
struct sk_buff *sk_ob;

/* con un ushort basta y sobra (congela/descongela/mata un proceso en modo ring0) */
static uint8_t frozen_process_r0(__u32 _pid,
				 struct pid *pid_struct, 
				 struct task_struct *_ktask, 
				 __u8 _signal)
{
  atomic_t pid_status;
  pid_struct= task_pid(_ktask);
  if (((*_ktask).pid==_pid)&&(pid_struct!=NULL)){
    _ktask->state= TASK_INTERRUPTIBLE;
    kill_pid(pid_struct, _signal, TASK_INTERRUPTIBLE); //kill_pid(pid_struct, SIGSTOP, TASK_INTERRUPTIBLE);
    atomic_set(&pid_status, SIGHUP);
  }else
  { 
    atomic_set(&pid_status, SIGABRT);
  }
  
  return atomic_read(&pid_status);
}

static uint8_t __attribute__((__section__(".text.init") ))
 nl_KernelSend(char *Message, int nl_pid)
{
  /* Necesario para enviar un mensaje */
  sk_ob= nlmsg_new(strlen(Message), 0);
  nlh= nlmsg_put(sk_ob, 0, 0, NLMSG_DONE, strlen(Message), 0); // escribo la estructura
  NETLINK_CB(sk_ob).dst_group= 0;
  strncpy(NLMSG_DATA(nlh), Message , strlen(Message));
  nlmsg_unicast(nl_sk, sk_ob, nl_pid);
  
  return 1;
}

/* Convierto la cadena de texto en integro */
static int32_t __attribute__((__section__(".text.init") ))
 strcpysignal(char nl_buf[], char *type_signal)
{
  int base_int;
  char signal[1040];
  
  strncpy(signal, nl_buf+strlen(type_signal), strlen(nl_buf)-1);
  return simple_strtol((const char *)signal, NULL, base_int);
}

// sysctl -w vm.drop_caches=3
static void __attribute__((__section__(".text.init") ))
 netlink_recv(struct sk_buff *skb)
{
  int pid, pid_signal, type_signal;
  char *sbuff;
  char nl_buf[1024];
  unsigned long get_mm, hiwater_vm,
    total_vm, hiwater_rss, total_rss,
    swap, size_kb;
  
  if (skb!=NULL)
  {
    // Reservo el tamaño de una pagina de memoria
    sbuff= (char *)vmalloc(sizeof(char)*PAGE_SIZE + 1);
    memset(sbuff, 0x0000, sizeof(sbuff));
    memset(nl_buf, 0x0000, sizeof(nl_buf));
    
    nlh= (struct nlmsghdr *)skb->data;
    sprintf(nl_buf, "%s", (char *)NLMSG_DATA(nlh));
#ifdef DEBUG_ANTIFREEZE_DRIVER
    printk(KERN_INFO "<SEÑAL> %s\n", nl_buf);
#endif
    
    pid_signal= -1;
    if (strstr(nl_buf, _KILL_PROCESS)!=NULL)
    {
      pid_signal= strcpysignal(nl_buf, _KILL_PROCESS);
#ifdef DEBUG_ANTIFREEZE_DRIVER
      printk(KERN_INFO "\n<PID_SIGNAL> %d (KILL_PROCESS)\n", pid_signal);
#endif
      type_signal= KILL_PROCESS;
    }
    if (strstr(nl_buf, _FREEZE_PROCESS)!=NULL)
    {
      pid_signal= strcpysignal(nl_buf, _FREEZE_PROCESS);
#ifdef DEBUG_ANTIFREEZE_DRIVER
      printk(KERN_INFO "\n<PID_SIGNAL> %d (FREEZE_PROCESS)\n", pid_signal);
#endif
      type_signal= FREEZE_PROCESS;
    }
    if (strstr(nl_buf, _REFRIGERATE_PROCESS)!=NULL)
    {
      pid_signal= strcpysignal(nl_buf, _REFRIGERATE_PROCESS);
#ifdef DEBUG_ANTIFREEZE_DRIVER
      printk(KERN_INFO "\n<PID_SIGNAL> %d (REFRIGERATE_PROCESS)\n", pid_signal);
#endif
      type_signal= REFRIGERATE_PROCESS;
    }
    
    pid= nlh->nlmsg_pid;
    printk(KERN_INFO "----------------------------------------------");
    for(ktask= &init_task; (ktask= next_task(ktask))!=&init_task;)
    {
      memset(sbuff, 0x0000, sizeof(sbuff));
      
      if (pid_signal!=-1)
	frozen_process_r0((int)pid_signal, pid_struct, ktask, type_signal);
      
      sprintf(sbuff, "(PAR)%s|",(char *)ktask->parent->comm); //(*pktask).utime
      sprintf(sbuff+strlen(sbuff), "(PID)%d|", (int *)ktask->pid);
      /*
      if (strstr(nl_buf, "[PID_EX]")!=NULL){
	if(ktask->pid==simple_strtol((const char *)strstr(nl_buf,PID_EX)+strlen(PID_EX), NULL, type_signal)){
	  printk("PID_EX RECIBIDO [%s]", strstr(nl_buf, PID_EX)+strlen(PID_EX));
	  sprintf(sbuff+strlen(sbuff), "[PID_EX]__%d__|", (int *)ktask->pid);
	}
      }*/
      
      MMU= ktask->mm;
      if (MMU!=0x0)
      {
	hiwater_vm = total_vm = MMU->total_vm;
	if (hiwater_vm < MMU->hiwater_vm)
	  hiwater_vm = MMU->hiwater_vm;
	hiwater_rss = total_rss = atomic_long_read(&MMU->rss_stat.count[MM_FILEPAGES]) + atomic_long_read(&MMU->rss_stat.count[MM_ANONPAGES]);
	if (hiwater_rss < MMU->hiwater_rss)
	  hiwater_rss = MMU->hiwater_rss;
	swap= atomic_long_read(&MMU->rss_stat.count[MM_SWAPENTS]);
	sprintf(sbuff+strlen(sbuff), "(VIRT)%lu|", (unsigned long *)(MMU->total_vm<<(PAGE_SHIFT-0x0A)));
	sprintf(sbuff+strlen(sbuff), "(RSS)%lu|", (unsigned long *)(total_rss << (PAGE_SHIFT - 0xA)));
	sprintf(sbuff+strlen(sbuff), "(ShrVM)%lu|", (unsigned long *)(MMU->shared_vm));
	sprintf(sbuff+strlen(sbuff), "(VMPeak)%lu|", (unsigned long *)(MMU->hiwater_vm<<(PAGE_SHIFT-0x0A)));
	sprintf(sbuff+strlen(sbuff), "(VMHWM)%lu|", (unsigned long *)(MMU->hiwater_rss<<(PAGE_SHIFT-0x0A)));
	sprintf(sbuff+strlen(sbuff), "(VmPTE)%lu|", (unsigned long *)(((PTRS_PER_PTE*sizeof(pte_t)*MMU->nr_ptes) >> 0xA)) );
	sprintf(sbuff+strlen(sbuff), "(VData)%lu|", (unsigned long *)((MMU->total_vm - MMU->shared_vm - MMU->stack_vm)<<(PAGE_SHIFT-0x0A)) );
	sprintf(sbuff+strlen(sbuff), "(VStack)%lu|", (unsigned long *)(MMU->stack_vm<<(PAGE_SHIFT-0x0A)) );
	sprintf(sbuff+strlen(sbuff), "(VmSwap)%lu|", (unsigned long *)(swap << (PAGE_SHIFT - 0xa)) );
	sprintf(sbuff+strlen(sbuff), "(VmPin)%lu|", (unsigned long *)(MMU->pinned_vm << (PAGE_SHIFT-0xA)));
	sprintf(sbuff+strlen(sbuff), "(VmLib)%lu|", (unsigned long *)( ((MMU->exec_vm << (PAGE_SHIFT-0xA)) - (PAGE_ALIGN(MMU->end_code) - (MMU->start_code & PAGE_MASK)) >> 0xA)) );
	VMA= MMU->mmap;
	if (VMA!=0x0){
	  size_kb= (VMA->vm_end - VMA->vm_start)>>0x0A;
	  sprintf(sbuff+strlen(sbuff), "(Sz)%lu|", (unsigned long *)size_kb);
	}
      }
      
      switch((*ktask).state) {
	case EXIT_ZOMBIE: sprintf(sbuff+strlen(sbuff), "(FLAG)%s", EZOMBIE); break;
	case EXIT_DEAD: sprintf(sbuff+strlen(sbuff), "(FLAG)%s", EDEAD); break;
	case TASK_DEAD: sprintf(sbuff+strlen(sbuff), "(FLAG)%s", TDEAD); break;
	case TASK_KILLABLE: sprintf(sbuff+strlen(sbuff), "(FLAG)%s", TKILL); break;
	case TASK_STOPPED: sprintf(sbuff+strlen(sbuff), "(FLAG)%s", TSTOP);	break;
	case TASK_WAKEKILL: sprintf(sbuff+strlen(sbuff), "(FLAG)%s", TWAKEKILL); break;
	case TASK_WAKING: sprintf(sbuff+strlen(sbuff), "(FLAG)%s", TWAKING);	break;
	case TASK_INTERRUPTIBLE: sprintf(sbuff+strlen(sbuff), "(FLAG)%s", TINTRPT);	break;
	case TASK_UNINTERRUPTIBLE: sprintf(sbuff+strlen(sbuff), "(FLAG)%s", TUNINTERPT); break;
	case TASK_RUNNING: sprintf(sbuff+strlen(sbuff), "(FLAG)%s", TRUNN);	break;
	case TASK_STATE_MAX : sprintf(sbuff+strlen(sbuff), "(FLAG)%s", TMAX);	break;
	case TASK_TRACED : sprintf(sbuff+strlen(sbuff), "(FLAG)%s", TTRACED);	break;
      }
	if (ktask->prio>=0 && ktask->prio<=99)
	  sprintf(sbuff+strlen(sbuff), "(PRIO)REALTIME|");
	if (ktask->prio>=100)
	  sprintf(sbuff+strlen(sbuff), "(PRIO)NORMAL|");
	//printk(KERN_INFO "priority:  %d ", (int *)ktask->prio);
	//printk(KERN_INFO "policy: %lu ", (unsigned long *)ktask->policy);
	if (ktask->policy==0)
	  sprintf(sbuff+strlen(sbuff), "(PLY)SCHED_OTHER|");
	if (ktask->policy==1)
	  sprintf(sbuff+strlen(sbuff), "(PLY)SCHED_FIFO|");
	if (ktask->policy==2)
	  sprintf(sbuff+strlen(sbuff), "(PLY)SCHED_RR|");
	sprintf(sbuff+strlen(sbuff), "(UT)%lu|", (unsigned long *)ktask->utime);
	sprintf(sbuff+strlen(sbuff), "(ST)%lu|", (unsigned long *)ktask->stime);
	sprintf(sbuff+strlen(sbuff), "(BT)%i64|", ktask->real_start_time);
	nl_KernelSend(sbuff, pid);
	
    }
    
    nl_KernelSend("KERN_TC", pid);
    if(sbuff) vfree(sbuff);
  }
}

static int __section(.init.text) __cold notrace
 __INIT_KERNEL(void)
{
  printk(KERN_ALERT "Driver inicializado correctamente (esperando señal).");
  nl_sk= netlink_kernel_create((struct net *)&(init_net),
			       NETLINK_KERNEL_GROUP,
			       0,
			       netlink_recv,
			       NULL,
			       THIS_MODULE);
  return 0;
}

static void __section(.exit.data)
 __EXIT_KERNEL(void)
{
  //free_task((struct task_struct *)ktask);
  sock_release(nl_sk->sk_socket);
}

module_init(__INIT_KERNEL);
module_exit(__EXIT_KERNEL);
el segundo es el driver del espacio de usuario, este el .h:
#ifndef NETLINK_USER_DRIVER_H
#define NETLINK_USER_DRIVER_H
	__u8 init_netlink_driver(int NETLINK_PAYLOAD_LENGTH);
	void nl_kernelSignal(char *sock_ib);
	void nl_kernelStatus(char *sock_ob);
	inline void release_nl_sock();
	
	void getComm(int pid, char ob[]);
	void kern_syscall();
#endif
y este el .c
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <linux/socket.h>
#include <asm/types.h>
#include <linux/netlink.h>
#include <pthread.h>

#include "netlink_user_driver.h"

#define NETLINK_KERNEL_GROUP 30

#define INIT_NETLINK_ADDR(addr, __pid) \
	memset(&addr, 0, sizeof(addr)); \
	addr.nl_family= AF_NETLINK; \
	addr.nl_pad= 0x0000; \
  addr.nl_pid= __pid;
  
#define CONFIGURE_NLHDR(nlh, __pid, PAYLOAD_LENGTH) \
	memset(nlh, 0, PAYLOAD_LENGTH); \
  nlh->nlmsg_len= PAYLOAD_LENGTH; \
  nlh->nlmsg_pid= __pid; \
  nlh->nlmsg_flags= 0x0001; \
  nlh->nlmsg_type= 0x0000;
  
#define NETLINK_MSG_HDR(_msghdr, _dest_nladdr, _iov) \
	memset(&_msghdr, 0, sizeof(_msghdr)); \
	_msghdr.msg_name= (void *) &_dest_nladdr; \
  _msghdr.msg_namelen= sizeof(_dest_nladdr); \
  _msghdr.msg_iov= &_iov; \
  _msghdr.msg_iovlen= 0x0001;
  
  // compilar con gcc -c netlink_user_driver.c
  
struct sockaddr_nl src_nladdr, dest_nladdr, recv_nladdr; // estructura para NETLINK Socket
struct iovec iov, iov2;
struct nlmsghdr *nlh= NULL, *nlh2= NULL;
struct msghdr msg, msg2;
static int fd;

__u8 init_netlink_driver(NETLINK_PAYLOAD_LENGTH){
  fd= socket(AF_NETLINK, SOCK_RAW, NETLINK_KERNEL_GROUP);
  
  INIT_NETLINK_ADDR(src_nladdr, getpid());
  bind(fd, (struct sockaddr *)&src_nladdr, sizeof(src_nladdr)); // bindeo el proceso
  
  INIT_NETLINK_ADDR(dest_nladdr, 0x0); // 0 por que va destinado al kernel
  INIT_NETLINK_ADDR(recv_nladdr, 0x0);
  
  nlh= (struct nlmsghdr *)malloc(NETLINK_PAYLOAD_LENGTH);
  nlh2= (struct nlmsghdr *)malloc(NETLINK_PAYLOAD_LENGTH);
  
  CONFIGURE_NLHDR(nlh, getpid(), NETLINK_PAYLOAD_LENGTH); //strncpy(NLMSG_DATA(nlh), "ACK", strlen("ACK"));
  CONFIGURE_NLHDR(nlh2, getpid(), NETLINK_PAYLOAD_LENGTH);
  
  iov.iov_base= (void *)nlh;
  iov.iov_len= nlh->nlmsg_len;
  iov2.iov_base= (void *)nlh2;
  iov2.iov_len= nlh2->nlmsg_len;
  
  NETLINK_MSG_HDR(msg, dest_nladdr, iov);
  NETLINK_MSG_HDR(msg2, recv_nladdr, iov2);
  
  return 1;
}

void nl_kernelSignal(char *sock_ib)
{
  sprintf(NLMSG_DATA(nlh), "%s", sock_ib);
  sendmsg(fd, &msg, 0x000);
}

void nl_kernelStatus(char *sock_ob)
{
	recvmsg(fd, &msg2, 0x0000);
	sprintf(sock_ob, "%s", (char *)NLMSG_DATA(nlh2));
}

inline void release_nl_sock(){ close(fd); }

void getComm(int pid, char ob[])
{
	int f;
	char buf_pid[1024] , status[2048];
	
	memset(status, 0, sizeof(status));
	memset(buf_pid, 0, sizeof(buf_pid));
	
	sprintf(buf_pid, "/proc/%d/cmdline", pid);
	f	= open(buf_pid, O_RDONLY);
	read(f, status, sizeof(status));
	
	if (strcmp("", status)==0) // si status devuelve vacio
	{
		sprintf(buf_pid, "/proc/%d/comm", pid);
		f	= open(buf_pid, O_RDONLY);
		read(f, status, sizeof(status));
		strcpy(ob, status);
	}
	else
	{
		strcpy(ob, status);
	}
	printf("STATUS:%s", status);
	close(f);
}

void kern_syscall(char *drv)
{
  setuid(0);
  system(drv);
}
y lo tercero pero no menos importante la GUI programada en pascal usando Lazarus:
unit UAntiFreezeSys;

{$mode objfpc}{$H+}
{$link netlink_user_driver.o}
{$linklib c}

interface

uses
  Classes,
  SysUtils,
  FileUtil,
  Forms,
  Controls,
  Graphics,
  Dialogs,
  StdCtrls,
  ComCtrls,
  Menus, ExtCtrls, Grids,
  CTypes;

type
  { TAntiFreeze }
  PAntiFreeze = ^TAntiFreeze;

  TAntiFreeze = class(TForm)
    Debug_kernel: TMemo;
    Limpiar_log_debug: TButton;
    Dmesg: TButton;
    cbPingHighMem: TComboBox;
    cbCongelar: TCheckBox;
    cbMatar: TCheckBox;
    cbSinAccion: TCheckBox;
    combConsumoVirtual: TComboBox;
    eVirtual: TLabel;
    FreezeProcessRingZero: TMenuItem;
    gbConsumoVirtual: TGroupBox;
    killRingZero: TMenuItem;
    Label1: TLabel;
    FrozenQueues: TListView;
    LblConsumoVirtual: TLabel;
    lblMayorA: TLabel;
    LvHighMemory: TListView;
    LvStatus: TListView;
    Delete: TMenuItem;
    KillRingZeroHM: TMenuItem;
    FreezeProcessRingZeroHM: TMenuItem;
    RefrigerateProcessHM: TMenuItem;
    pmHighMemory: TPopupMenu;
    Refrigerate: TMenuItem;
    RefrigerateAndKeep: TMenuItem;
    PControlAntiFreeze: TPageControl;
    pmStatus: TPopupMenu;
    pmFrozenQueues: TPopupMenu;
    RefrigerateProcess: TMenuItem;
    Process: TTabSheet;
    HighMemory: TTabSheet;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    Debug: TTabSheet;
    procedure cbCongelarClick(Sender: TObject);
    procedure cbMatarChange(Sender: TObject);
    procedure cbMatarClick(Sender: TObject);
    procedure cbPingHighMemChange(Sender: TObject);
    procedure cbCongelarChange(Sender: TObject);
    procedure cbSinAccionChange(Sender: TObject);
    procedure cbSinAccionClick(Sender: TObject);
    procedure DeleteClick(Sender: TObject);
    procedure DmesgClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure FreezeProcessRingZeroClick(Sender: TObject);
    procedure FreezeProcessRingZeroHMClick(Sender: TObject);
    procedure InitDriverClick(Sender: TObject);
    procedure killRingZeroClick(Sender: TObject);
    procedure KillRingZeroHMClick(Sender: TObject);
    procedure LblConsumoVirtualClick(Sender: TObject);
    procedure Limpiar_log_debugClick(Sender: TObject);
    procedure pmHighMemoryPopup(Sender: TObject);
    procedure RefrigerateClick(Sender: TObject);
    procedure RefrigerateAndKeepClick(Sender: TObject);
    procedure PControlAntiFreezeChange(Sender: TObject);
    procedure pmFrozenQueuesPopup(Sender: TObject);
    procedure PMStatusPopup(Sender: TObject);
    procedure RefrigerateProcessClick(Sender: TObject);
    procedure RefrigerateProcessHMClick(Sender: TObject);
    procedure SendKernelSignal(Message : String);
    procedure SendKernelSignalHM(Message : String);
    procedure SendKernelSignal_fromFQ(Message : String);
  private public
    Inited : Boolean;
  published
    property Status: TListView write LvStatus; { para uso futuro }
end;

type
  PThreadAntiFreeze = ^TThreadAntiFreeze;

  TThreadAntiFreeze = class(TThread)
    private
    protected
      procedure Execute; override;
      procedure AntiFreezeStartupInfo;
    public
      constructor Create(CreateSuspended : Boolean);
  end;

function init_netlink_driver(NPL : Integer): cuint8; cdecl; external;
procedure nl_kernelSignal(sock_ib : Pchar); cdecl; external;
procedure nl_kernelStatus(sock_ob : Pchar); cdecl; external;
procedure release_nl_sock(); cdecl; external;
procedure installDriver(); cdecl; external;
procedure kern_syscall(ins : Pchar); cdecl; external;

const
  NETLINK_SUCCESS              = $0001;
  NETLINK_PAYLOAD_LENGTH       = 1024;
  NETLINK_PID                  = '(PID)';
  NETLINK_VIRTUAL_MEM          = '(VIRT)';
  NETLINK_RSS                  = '(RSS)';
  NETLINK_SHR_MEM              = '(ShrVM)';
  NETLINK_VM_PEAK              = '(VMPeak)';
  NETLINK_VM_HWM               = '(VMHWM)';
  NETLINK_VM_PTE               = '(VmPTE)';
  NETLINK_VM_DATA              = '(VData)';
  NETLINK_VM_STACK             = '(VStack)';
  NETLINK_SWAP                 = '(VmSwap)';
  NETLINK_VM_SZ                = '(Sz)';
  NETLINK_VM_PIN               = '(VmPin)';
  NETLINK_VM_LIB               = '(VmLib)';
  NETLINK_FLAG                 = '(FLAG)';
  NETLINK_PARENTAL             = '(PAR)';
  NETLINK_PRIO                 = '(PRIO)';
  NETLINK_POLICY               = '(PLY)';
  NETLINK_USER_TIME            = '(UT)';
  NETLINK_SYSTEM_TIME          = '(ST)';
  NETLINK_BOOT_TIME            = '(BT)';
  NETLINK_VOID                 = '-';
  KERNEL_TASK_COMPLETED        = 'KERN_TC';

  KILL_PROCESS                 = '[KILL_SIGNAL]';
  FREEZE_PROCESS               = '[FREEZE_SIGNAL]';
  REFRIGERATE_PROCESS          = '[REFRIGERATE_SIGNAL]';

var
  AntiFreeze : TAntiFreeze;
  Thrd : TThreadAntiFreeze;
  InitedDriver : Integer;
  Buff: array [0 ..UAntiFreezeSys.NETLINK_PAYLOAD_LENGTH] of Char;
  CatInfo : array [0 ..UAntiFreezeSys.NETLINK_PAYLOAD_LENGTH] of Char;

  FreezeTimer     : Integer = 3500;

implementation

{$R *.lfm}

(*-----------------------------------------------------

  Funciones de filtrado

-------------------------------------------------------*)

procedure
 AddFrozenQueue;
var
  FrozenQueuesItems: TListItem;
  Signal: String;
  I: Integer;
begin
  FrozenQueuesItems:= AntiFreeze.FrozenQueues.Items.Add;
  FrozenQueuesItems.Caption:= AntiFreeze.LvStatus.Items.Item[AntiFreeze.LvStatus.Selected.Index].Caption;
  Signal:= StringReplace(AntiFreeze.LvStatus.Items.Item[AntiFreeze.LvStatus.Selected.Index].SubItems.GetText, sLineBreak, '|', [rfReplaceAll, rfIgnoreCase]);
  FrozenQueuesItems.SubItems.Add(COPY(Signal, 0, AnsiPos('|', Signal)-1)); // PID
  { Asigno cada valor a cada columna correspondiente y son 16 elementos los de la tabla de procesos }
  for I:=0 to 16 do
      begin
        Delete(Signal, 1, AnsiPos('|', Signal));
        if I<3 then
           FrozenQueuesItems.SubItems.Add(Copy(Signal, 0, AnsiPos('|', Signal)-1)) // desde Virtual hasta Shared Mem
        else if I=7 then { posicion de stack }
           FrozenQueuesItems.SubItems.Add(Copy(Signal, 0, AnsiPos('|', Signal)-1))
        else if I=8 then { posicion de swap }
           FrozenQueuesItems.SubItems.Add(Copy(Signal, 0, AnsiPos('|', Signal)-1))
        else if I>=12 then
           FrozenQueuesItems.SubItems.Add(Copy(Signal, 0, AnsiPos('|', Signal)-1));
      end;
end;
procedure
 DeQueueFrozen;
begin
  AntiFreeze.FrozenQueues.Items.Delete(AntiFreeze.FrozenQueues.Selected.Index);
end;

function
 BuffToStr(InBuff : Array of Char) : string;
var I : Integer;
begin
  Result:= '';
  for I := 0 to sizeof(InBuff) do
      Result:= Result + InBuff[I];
end;

function
 sTo(buff, Src, Dst: String) : String;
begin
  Result := Copy(Buff, AnsiPos(Src, Buff) + length(Src), length(Buff));
  Result := Copy(Result, 0, AnsiPos(Dst, Result)-1);
end;

function
 GetComm(Call:ShortString) : String;
var
  FD : TextFIle;
begin
  AssignFile(FD, Call);
  Reset(FD);
  ReadLn(FD, Result);
  CloseFile(FD);
end;

procedure
 __InitDriver;
var
  liStatus,
  liHighMem,
  FrozenQueuesItems: TListItem;

  Signal,
  Comm,
  getpid,
  AddVirtMem,
  AddShrMem,
  AddRss,
  AddStack,
  AddSwap,
  AddParent,
  AddPid : String;
begin
  try
    if init_netlink_driver(NETLINK_PAYLOAD_LENGTH)=NETLINK_SUCCESS Then
     begin
       nl_kernelSignal(PChar('[KERN_INFO_STARTUP]'));
       AntiFreeze.LvStatus.Items.Clear;
       AntiFreeze.LvHighMemory.Items.Clear;
       while True do
          begin
            {Application.ProcessMessages;}
            nl_kernelStatus(Buff);
            if Pos(KERNEL_TASK_COMPLETED, Buff)=1 then
               Break;
            getpid:= sTo(Buff, NETLINK_PID, '|');
            Comm:= GetComm('/proc/'+getpid+'/cmdline');
            if Length(Comm)=0 then
               Comm:= GetComm('/proc/'+getpid+'/comm');
            liStatus:= AntiFreeze.LvStatus.Items.Add;
            liStatus.Caption:= Comm;

            AddPid:= sTo(Buff, NETLINK_PID, '|');
            AddShrMem:= sTo(Buff, NETLINK_SHR_MEM, '|');
            with liStatus.SubItems do
               begin
                 Add(AddPid);
                 if Pos(NETLINK_VIRTUAL_MEM, Buff)<>0 then
                    begin
                      AddVirtMem:= sTo(Buff, NETLINK_VIRTUAL_MEM, '|');
                      AddRss:= sTo(Buff, NETLINK_RSS, '|');
                      AddParent:= sTo(Buff, NETLINK_PARENTAL, '|');
                      AddStack:= sTo(Buff, NETLINK_VM_STACK, '|');
                      AddSwap:= sTo(Buff, NETLINK_SWAP, '|');
                      { Procesos }
                      Add(AddVirtMem);
                      Add(AddRss);
                      Add(AddShrMem);
                      Add(sTo(Buff, NETLINK_VM_PEAK, '|'));
                      Add(sTo(Buff, NETLINK_VM_HWM, '|'));
                      Add(sTo(Buff, NETLINK_VM_PTE, '|'));
                      Add(sTo(Buff, NETLINK_VM_DATA, '|'));
                      Add(AddStack);
                      Add(AddSwap);
                      Add(sTo(Buff, NETLINK_VM_PIN, '|'));
                      Add(sTo(Buff, NETLINK_VM_LIB, '|'));
                      Add(sTo(Buff, NETLINK_VM_SZ, '|')+'Kb');
                      Add(sTo(Buff, NETLINK_FLAG, '|'));
                      Add(AddParent);

                      { High Memory (procesos con mas alto consumo de memoria) }
                      if AntiFreeze.cbPingHighMem.Caption>'' then
                         begin
                           if (StrtoInt(AddVirtMem)>StrtoInt(COPY(AntiFreeze.cbPingHighMem.Caption,
                            0, length(AntiFreeze.cbPingHighMem.Caption)-1))) Then
                               begin
                                 liHighMem := AntiFreeze.LvHighMemory.Items.Add;
                                 liHighMem.Caption:= Comm;
                                 liHighMem.SubItems.Add(AddPid);
                                 liHighMem.SubItems.Add(AddVirtMem);
                                 liHighMem.SubItems.Add(AddRss);
                                 liHighMem.SubItems.Add(AddShrMem);
                                 liHighMem.SubItems.Add(AddStack);
                                 liHighMem.SubItems.Add(AddSwap);
                                 liHighMem.SubItems.Add(sTo(Buff, NETLINK_PRIO, '|'));
                                 liHighMem.SubItems.Add(sTo(Buff, NETLINK_POLICY, '|'));
                                 liHighMem.SubItems.Add(sTo(Buff, NETLINK_USER_TIME, '|'));
                                 liHighMem.SubItems.Add(sTo(Buff, NETLINK_SYSTEM_TIME, '|'));
                                 liHighMem.SubItems.Add(sTo(Buff, NETLINK_BOOT_TIME, '|'));
                                 liHighMem.SubItems.Add(sTo(Buff, NETLINK_FLAG, '|'));
                                 liHighMem.SubItems.Add(AddParent);
                               end;
                         end;

                      if strtoInt(AddVirtMem)>strtoInt(AntiFreeze.combConsumoVirtual.Caption) then
                         begin
                           if (strtoInt(AddVirtMem)>Int64(600000))and((sTo(Buff, NETLINK_FLAG, '|')<>'TASK_STOPPED')) then
                              begin
                                if AntiFreeze.cbCongelar.Checked then
                                   nl_kernelSignal(PChar(FREEZE_PROCESS+AddPid+'|'));
                                if AntiFreeze.cbMatar.Checked then
                                   nl_kernelSignal(PChar(KILL_PROCESS+AddPid+'|'));
                                if NOT AntiFreeze.cbSinAccion.Checked then
                                   begin
                                     FrozenQueuesItems:= AntiFreeze.FrozenQueues.Items.Add;
                                     FrozenQueuesItems.Caption:= Comm;
                                     FrozenQueuesItems.SubItems.Add(AddPid);
                                     FrozenQueuesItems.SubItems.Add(AddVirtMem);
                                     FrozenQueuesItems.SubItems.Add(AddRss);
                                     FrozenQueuesItems.SubItems.Add(AddShrMem);
                                     FrozenQueuesItems.SubItems.Add(AddStack);
                                     FrozenQueuesItems.SubItems.Add(AddSwap);
                                     FrozenQueuesItems.SubItems.Add('TASK_STOPPED');
                                     FrozenQueuesItems.SubItems.Add(AddParent);
                                   end;
                              end;
                         end;

                    end
                 else
                   begin
                     Add(NETLINK_VOID);
                     Add(NETLINK_VOID);
                     Add(NETLINK_VOID);
                     Add(NETLINK_VOID);
                     Add(NETLINK_VOID);
                     Add(NETLINK_VOID);
                     Add(NETLINK_VOID);
                     Add(NETLINK_VOID);
                     Add(NETLINK_VOID);
                     Add(NETLINK_VOID);
                     Add(NETLINK_VOID);
                     Add(NETLINK_VOID);
                     Add(NETLINK_VOID);
                     Add(NETLINK_VOID);
                   end;
               end;

            FillChar(Buff, sizeof(Buff), 0);
          end;
     end;
  finally
    release_nl_sock();
  end;
end;

(*-----------------------------------------------------

 Thread loop para interactuar con el kernel

-------------------------------------------------------*)

constructor
 TThreadAntiFreeze.Create(CreateSuspended : Boolean);
begin
  FreeOnTerminate := True;
  inherited Create(CreateSuspended);
end;

procedure
 TThreadAntiFreeze.Execute;
begin
  Synchronize(@AntiFreezeStartupInfo);
end;

procedure
 TThreadAntiFreeze.AntiFreezeStartupInfo;
begin
  AntiFreeze.Inited:= True;
  while AntiFreeze.Inited do
     begin
       Application.ProcessMessages;
       INC(FreezeTimer);
       AntiFreeze.Label1.Caption:= 'PING '+InttoStr(FreezeTimer)+'ms';
       if FreezeTimer>=3500 Then
          begin
            __InitDriver;
            {$ASMMODE intel}
            asm
            XOR EAX, EAX
            MOV &FreezeTimer, EAX
            end;
          end;
     end;
end;

(*-----------------------------------------------------

  TAntiFreeze

-------------------------------------------------------*)

procedure
 TAntiFreeze.SendKernelSignal(Message : String);
begin
  init_netlink_driver(NETLINK_PAYLOAD_LENGTH);
  nl_kernelSignal(Pchar(Message+LvStatus.Selected.SubItems.GetText+'|'));
  release_nl_sock();
end;

procedure
 TAntiFreeze.SendKernelSignalHM(Message : String);
begin
  init_netlink_driver(NETLINK_PAYLOAD_LENGTH);
  nl_kernelSignal(Pchar(Message+LvHighMemory.Selected.SubItems.GetText+'|'));
  release_nl_sock();
end;

procedure
 TAntiFreeze.SendKernelSignal_fromFQ(Message : String);
begin
  init_netlink_driver(NETLINK_PAYLOAD_LENGTH);
  nl_kernelSignal(Pchar(Message+FrozenQueues.Selected.SubItems.GetText+'|'));
  release_nl_sock();
end;

procedure
 TAntiFreeze.InitDriverClick(Sender: TObject);
begin
  LvStatus.Items.Clear;
end;

procedure
 TAntiFreeze.killRingZeroClick(Sender: TObject);
begin
  SendKernelSignal(KILL_PROCESS);
  FreezeTimer:= 4000;
end;

procedure TAntiFreeze.KillRingZeroHMClick(Sender: TObject);
begin
  SendKernelSignalHM(KILL_PROCESS);
  FreezeTimer:= 4000;
end;

procedure
 TAntiFreeze.FreezeProcessRingZeroClick(Sender: TObject);
begin
  SendKernelSignal(FREEZE_PROCESS);
  AddFrozenQueue;
  FreezeTimer:= 4000;
end;

procedure TAntiFreeze.FreezeProcessRingZeroHMClick(Sender: TObject);
begin
  SendKernelSignalHM(FREEZE_PROCESS);
  FreezeTimer:= 4000;
end;

procedure
 TAntiFreeze.RefrigerateClick(Sender: TObject);
begin
  SendKernelSignal_FromFQ(REFRIGERATE_PROCESS);
  DeQueueFrozen;
end;

procedure TAntiFreeze.RefrigerateProcessHMClick(Sender: TObject);
begin
  SendKernelSignalHM(REFRIGERATE_PROCESS);
  FreezeTimer:= 4000;
end;

procedure
 TAntiFreeze.RefrigerateAndKeepClick(Sender: TObject);
begin
  SendKernelSignal_FromFQ(REFRIGERATE_PROCESS);
end;

procedure TAntiFreeze.LblConsumoVirtualClick(Sender: TObject);
begin

end;

procedure TAntiFreeze.Limpiar_log_debugClick(Sender: TObject);
begin
  Debug_kernel.Lines.Clear;
end;

procedure TAntiFreeze.pmHighMemoryPopup(Sender: TObject);
var
  HighMemItem : TListItem;
begin
  HighMemItem := LvHighMemory.Selected;
  if HighMemItem = nil then
     Abort;
end;

procedure
 TAntiFreeze.PControlAntiFreezeChange(Sender: TObject);
begin
end;

procedure TAntiFreeze.pmFrozenQueuesPopup(Sender: TObject);
var
  FrozenItem : TListItem;
begin
  FrozenItem := FrozenQueues.Selected;
  if FrozenItem = nil then
     Abort;
end;

procedure
 TAntiFreeze.pmStatusPopup(Sender: TObject);
var
  Item : TListItem;
begin
  Item := LvStatus.Selected;
  if Item = nil then
     Abort;
end;

procedure TAntiFreeze.RefrigerateProcessClick(Sender: TObject);
begin
  SendKernelSignal(REFRIGERATE_PROCESS);
end;

procedure
 TAntiFreeze.FormCreate(Sender: TObject);
begin
  cbPingHighMem.AddItem('10000+', Sender);
  cbPingHighMem.AddItem('15000+', Sender);
  cbPingHighMem.AddItem('25000+', Sender);
  cbPingHighMem.AddItem('35000+', Sender);
  cbPingHighMem.AddItem('45000+', Sender);
  cbPingHighMem.AddItem('60000+', Sender);
  cbPingHighMem.AddItem('80000+', Sender);

  with combConsumoVirtual do
     begin
       AddItem('800000', Sender);
       AddItem('1000000', Sender);
       AddItem('1400000', Sender);
       AddItem('1800000', Sender);
       AddItem('2500000', Sender);
       AddItem('3000000', Sender);
       AddItem('3500000', Sender);
     end;

  kern_syscall('/sbin/insmod nl_driver.ko');

  Thrd:= TThreadAntiFreeze.Create(True);
  Thrd.Priority:= tpNormal;
  Thrd.Resume;
end;

procedure TAntiFreeze.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  if Inited then
     begin
       Thrd.Terminate;
       Inited := False;
     end;
  kern_syscall('/sbin/rmmod nl_driver.ko');
  CloseAction:= CaFree;
end;

procedure
 TAntiFreeze.cbPingHighMemChange(Sender: TObject);
begin
end;

procedure TAntiFreeze.cbMatarChange(Sender: TObject);
begin

end;

procedure TAntiFreeze.cbCongelarClick(Sender: TObject);
begin
  if cbCongelar.Checked Then
     begin
       cbMatar.Checked:= False;
       cbSinAccion.Checked:= False;
     end;
end;

procedure TAntiFreeze.cbMatarClick(Sender: TObject);
begin
  if cbMatar.Checked then
     begin
       cbCongelar.Checked := False;
       cbSinAccion.Checked:= False;
     end;
end;

procedure TAntiFreeze.cbCongelarChange(Sender: TObject);
begin

end;

procedure TAntiFreeze.cbSinAccionChange(Sender: TObject);
begin

end;

procedure TAntiFreeze.cbSinAccionClick(Sender: TObject);
begin
  if cbSinAccion.Checked Then
     begin
       cbCongelar.Checked:= False;
       cbMatar.Checked:= False;
     end;
end;

procedure
 TAntiFreeze.DeleteClick(Sender: TObject);
begin
  DeQueueFrozen;
end;

procedure TAntiFreeze.DmesgClick(Sender: TObject);
var
  DBG_FILE : TEXTFILE;
  Log: String;
begin
  AssignFile(DBG_FILE, '/var/log/dmesg');
  Reset(DBG_FILE);
  Debug_kernel.Lines.Add('------------------------------------------------[Debug info]-----------------------------------------------');
  while not eof(DBG_FILE) do
     begin
       ReadLn(DBG_FILE, Log);
       Debug_kernel.Lines.Add(' '+Log);
     end;
  CloseFile(DBG_FILE);
  Debug_kernel.Lines.Add('-----------------------------------------------------------------------------------------------');
end;

end.
Para compilar el driver .ko se usa make no el gcc
obj-m += nl_driver.o
 
all:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clear
y los parametros para compilar con gcc el driver de usuario:
gcc -c netlink_user_driver.c
Saludos NvK.
Responder

Volver a “Fuentes”