API Changes im 2.6.25er Kernel

02/05/2008 - 11:01 von Alexander Griesser | Report spam
Griass eich!

Ich habe mal zwei kleine Fragen zum 2.6.25er Kernel.
Die API hat sich ja teilweise wiedermal geàndert, was mich vor ein
kleineres und ein etwas größeres Problem stellt.

Punkt 1:

Wie kriege ich ohne die Verwendung von num_booting_cpus() heraus,
wieviele CPUs online sind?
Wenn ich num_booting_cpus() mit 2.6.25 verwende, dann kriege ich
beim Kompilieren die Fehlermeldung, dass das Symbol cpu_callout_map
nicht definiert ist (num_booting_cpus() verwendet dieses Symbol).

Derweil hab ich mir damit beholfen, auf diese Abfrage zu verzichten
und hab einfach mal "1" als Standardwert angenommen, aber ich will
eigentlich schon wissen, mit wievielen CPUs ich es zu tun habe.

Ein weiterer Versuch von mir schaute so aus:

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
int cpu = 0;
for_each_possible_cpu(cpu) { cpu++; };
return cpu;
#else
return num_booting_cpus();
#endif

Hat soweit scheinbar funktioniert, bin mir aber nicht sicher, ob das in
Ordnung ist bzw. ob man das so macht.


Punkt 2:

init_mm wird nicht mehr exportiert. Wie locke ich jetzt meine page
tables? Aufgrund des Changelog Eintrages für 2.6.25 siehts fast so
aus als ob man nie und nimmer init_mm hàtte verwenden sollen, naja,
mir war keine andere Variante bekannt, deshalb hier meine Frage:
Wie realisiert man sowas nun, ohne auf init_mm zurückgreifen zu
müssen?

Ich hab - ebenfalls durch Google - einen Code Snippet für alte 2.2er
Kernels gefunden wo das Problem auch schon mal da war, da hats dann
einen Workaround gegeben, mit dem man sich init_mm selbst erzeugen
konnte, der funktioniert aber unter 2.6.25 nicht mehr (Page faults):

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
static struct mm_struct *init_mm_ptr;
#define init_mm (*init_mm_ptr)

struct task_struct *p;

for(p = current; (p = p->tasks.next) != current; )
if(p->pid == 0)
break;

init_mm_ptr = p->mm;
#endif


Im Prinzip würde ich mir gerne eine Page holen (bisher hat folgendes
einwandfrei funktioniert):

spin_lock(&init_mm.page_table_lock);
page = vmalloc_to_page((void*)kaddr);
spin_unlock(&init_mm.page_table_lock);

Nun gibt ja init_mm nicht mehr, was nun?

Vielleicht kann mir ja wer helfen, Google ist nicht sehr hilfreich in
dieser Hinsicht und die Kernel-ML will ich mit meinen Problemchen auch
nicht belàstigen.

ciao && Danke,
Alex
 

Lesen sie die antworten

#1 Thomas Ogrisegg
03/05/2008 - 05:34 | Warnen spam
Alexander Griesser wrote on 2008-05-02:
Wie kriege ich ohne die Verwendung von num_booting_cpus() heraus,
wieviele CPUs online sind?



cpus_weight (cpu_online_map)

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
int cpu = 0;
for_each_possible_cpu(cpu) { cpu++; };
return cpu;
#else
return num_booting_cpus();
#endif

Hat soweit scheinbar funktioniert, bin mir aber nicht sicher, ob das in
Ordnung ist bzw. ob man das so macht.



Der gibt Dir nicht die Anzahl der "online"-CPUs, sondern die der
insgesamt vorhandenen.

Ich hab - ebenfalls durch Google - einen Code Snippet für alte 2.2er
Kernels gefunden wo das Problem auch schon mal da war, da hats dann
einen Workaround gegeben, mit dem man sich init_mm selbst erzeugen
konnte, der funktioniert aber unter 2.6.25 nicht mehr (Page faults):

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
static struct mm_struct *init_mm_ptr;
#define init_mm (*init_mm_ptr)

struct task_struct *p;

for(p = current; (p = p->tasks.next) != current; )
if(p->pid == 0)
break;

init_mm_ptr = p->mm;
#endif



Das segfaultet Dir deshalb, weil die task_struct linked List nicht mehr
in sich geschlossen ist, sondern beim letzten Prozess aufhoert (d.h.
eine Abfrage auf (p == NULL) waere notwendig gewesen). Wesentlich
einfacher ist onehin:

init_mm_ptr = init_task.mm

wobei das designmaessig vermutlich *aeusserst* eklig ist, also nicht zu
empfehlen.

Ähnliche fragen