#Zinnia

1 messages ยท Page 6 of 1

near tartan
#

hm

#

the problem is that i want the read of thread to be atomic

#

otherwise i'd just return gs:0 and cast the struct

#

but that's not atomic afaict

hoary cave
#

yeah no you can't do that with reference counting

#

you need a raw pointer/reference

near tartan
#

damn

#

i can do Arc::into_raw

#

that i can assemble with Arc::from_raw

hoary cave
#

sure but then you could just store an Arc

#

lol

near tartan
#

huh

hoary cave
#

why bother with gs:0 then

#

if you can just get a pointer to per cpu data

#

and grab the arc out of it yourself

near tartan
#

well that's not atomic, no?

hoary cave
#

i guess

near tartan
#

this is what i'm working on rn

hoary cave
#

O_O

near tartan
#

get_per_cpu works, but get_thread doesn't (because trash code)

hoary cave
#

yeah i guess you could just Arc::into_raw to leak it and then Arc::from_raw

#

don't forget to drop(Arc::from_raw(...)) when replacing the current thread pointer :^)

near tartan
#

duh

#

okay fuck

#

i need a better way of setting up percpu data

#

uacpi wants to read the current thread id, but there is no thread running at that point

#

i do:

  • uacpi init
  • cpu init using madt
hoary cave
#

you should have a "main kernel thread"

near tartan
#

no i mean like, gsbase is not set at that point

#

:(

hoary cave
#

realistically it's the first thing you should do meme

#

and current thread shouldn't be an Option tbh

near tartan
#

i guess

hoary cave
#

you can't not be running any thread

#

you always are running within the context of a thread

near tartan
#

how do i initialize it though

hoary cave
#

you just do

#

for the bsp

near tartan
#

i have no scheduler running :P

hoary cave
#

you can have a static percpu

near tartan
#

maybe some section hack can do?

hoary cave
#

why

#

just static

somber solar
#

or just random value

near tartan
#

that might work for the time being, but in the future this won't be sufficient

somber solar
#

why not?

#

just add a check if the scheduler is initialised

near tartan
#

because i might schedule jobs

#

on other threads

near tartan
#

i would rather just have the scheduler with a static thread to start with

hoary cave
#

just initialize your bsp idle thread from a static variable and when you initialize everything repurpose _start as it's idle loop

#

that would be bsp's current thread when you initialize the bsp per cpu data

#

(you can also do that from a static)

#

ideally you'd do that before anything else

#

i.e first thing after reaching _start

near tartan
#

hm then i need to rip a lot of this code out

#

woe

#

i think it would be better if we can look at this together tonight

#

i'm probably going to fuck this up in some way lol

#

like

#

ideally i would like the scheduler to be ready ASAP

hoary cave
#

i mean i can try to help but i'm not sure i'm more capable of doing this than yourself meme

near tartan
#

2 > 1

hoary cave
#

yep

near tartan
#

the scheduler should be setup statically, if that's even possible

#

maybe some const fn hacks

hoary cave
#

oh shit, arc allocates memory

near tartan
#

yes

hoary cave
#

no good

near tartan
#

it's not const

#

maybe arc is the wrong type for this use case

hoary cave
#

no it's not

#

it's just what we're trying to do doesn't work with an Arc :^)

near tartan
#

shit

#

maybe get_or_init???

hoary cave
#

but you definitely want to refcount your threads

#

that could work but

#

that requires a memory allocator to be up

near tartan
#

well menix initializes in stages

#

early, memory and init

#

everything relevant happens in init

hoary cave
#

ideally the per cpu data would be initialized early...

near tartan
#

we can set it up after the memory stage

#

btw it would be very funny if we could do something like managarm stages

#

maybe @marble salmon can explain how it works

hoary cave
#

initgraph

#

just a graph

#

there's code you can read

near tartan
#

i have tried

hoary cave
#

kernel/common/initgraph.hpp

#

but yeah

near tartan
#

gave me linux syndrome

#

would be very cool to have as well

hoary cave
#

but i'm not sure if it fits well into the rust type system

#

with like

#

borrow checking and all meme

#

thought i think there aren't any cyclic references

#

so it should be fine

near tartan
#

@hoary cave do you think we should use an Arc for the page table as well?

hoary cave
#

it would be nice

near tartan
#

cuz currently it just does this

hoary cave
#

to be able to refcount the page tables

near tartan
#

which is obviously a violation

hoary cave
#

the small problem with using an Arc for the [PageTableEntry; 512] thing is that it is already 4096 bytes big

#

at least on x86_64

#

and you doing Arc<[...; 4096], PageAlloc> would alloc two pages per page table

#

since it needs to allocate metadata too

#

which.. sucks

near tartan
#

i think there needs to be a better solution for phys mem alloc

hoary cave
#

so i suggest Arc'ing the wrapper around page tables

near tartan
#

i don't think we should rely on an allocator crate tbh

hoary cave
#

and deallocating the actual page table page in Drop

marble salmon
#

why do you need to refcount page tables?

near tartan
#

i guess so you don't drop a thread's page table when it's still being worked on

near tartan
#

@hoary cave i ended up changing all uses of VirtAddr and PhysAddr to be like what maestro does

#

i.e. transparent structs with a usize field

#

that way you can't accidentally use a physaddr in place of a virtual one

#

(i found 2 places where this happened)

#

i think it's time to do the scheduler

somber solar
#

what are you planning for it?

near tartan
#

nothing too fancy yet

#

round robin probably

#

a CFS would be nice

#

i do have to nuke/redo the per cpu init code

#

because it won't work as i intended

#

it basically combined cpu setup + tcb setup which is suboptimal

somber solar
near tartan
#

if i want to be very fancy, i might even abstract the algorithm away behind a cargo feature

near tartan
#

thread control block

#

= per cpu data

somber solar
#

ah

near tartan
#

idk how to design the api properly

#

oh damn i also need to do the website at some point ๐Ÿ’€

somber solar
#

for menix?

near tartan
#

yes

near tartan
#

i'm a brainlet

hoary cave
#

same

near tartan
#

i changed the kernel boot order so instead of
limine -> arch init -> main
it does
arch init -> main -> limine -> main

#

but i forgot that limine calls the kernel itself

#

so it kept initializing itself

near tartan
#

@hoary cave i may be cooking

somber solar
somber solar
near tartan
#

but for now it's unused

#

i guess i can add it later

somber solar
#

lol

near tartan
#

i mean qemu supports cpu hotplug

somber solar
#

wha

near tartan
somber solar
#

I guess that could be useful for multi socket servers

near tartan
#

most machines don't allow you to do this (because coolers and so on), but it's still funny

pine rock
#

you can scale an instance up and down as demand changes

#

until one guy caches the result of std::thread::hardware_concurrency() at which point you can now not scalememe

full topaz
#

has there been any real hardware that supports cpu hotplug?

near tartan
#

s390 trl

eternal wharf
#

i want the surprise unplug kind of hotplug

#

for cpus

near tartan
#

yes

cyan nexus
#

how would that even work?

#

thread currently being executed gets nuked?

near tartan
#

yes

#

you could "prepare" for it by marking the percpu data as offline

full topaz
near tartan
#

yes

full topaz
#

(or windows server for that matter)

full topaz
#

thats also a way to upgrade a server without downtike ih

#

ig*

near tartan
#

windows server barely functions on arm

#

๐Ÿ’€

full topaz
pine rock
#

Windows server can do hotplug but not unplug

#

And it produces some really fucky thread groups when you do hotplug

full topaz
pine rock
#

because they say it in their whitepaper on hotplug support?

full topaz
pine rock
#

mostly marketing fluf but yes

#

also you can literally download windows server and run it

full topaz
near tartan
#

my code actually works now

#

i can print per cpu data

somber solar
#

None

near tartan
#

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

#

i think i finally figured out why i keep getting page faults

#

i swap away the gsbase ๐Ÿ—ฟ

#

but not back

#

how did i not see this

near tartan
#

OH MY FUCKING GOD

#

i swapped the pop and push registers

#

they pop/push in the same order

#

instead of opposite order

#

wow so cool now i don't get random allocation failures

#

hell yes

#

can confirm that everything is working as intended now

#

even runs flawlessly on all my laptops

#

so the only thing left to do is to switch to my own allocator

#

correction: almost all laptops

#

but that's fixable

#

stupid ass hp envy

full topaz
somber solar
#

@near tartan shouldn't all these use p_filesz

near tartan
#

no

#

memsz = what's in memory
filesz = what to load into memory

somber solar
#

yes

near tartan
#

there may be zeroed memory

somber solar
#

if it's zeroed memory, what's the point of iterating over it

#

it's basically "allocate more, read less, iterate over more"

near tartan
#

null tag could be done like that meme

#

also don't forget that the dynamic segment may contain other things than tags (although that's probably not correct)

somber solar
#

so I don't see how it's related to elf contents

near tartan
#

that alloc should be a zeroing alloc

somber solar
#

it still doesn't make any sense, because no case would match in that switch to zeroed memory

near tartan
#

ah good catch, there should be a break in there if a DT_NULL is hit

somber solar
#

wait if it's just zero after p_filesz and you know it'll be matched, why even allocate and read memsz

near tartan
#

spec shenanigans, the other PT headers like PT_LOAD do the same

somber solar
#

I am become confucius, master at being confused

near tartan
#

like, this is how the .bss works

somber solar
#

yes but the allocated memory isn't used anywhere

near tartan
#

filesz 0, but memsz !0

somber solar
near tartan
#

does it matter?

#

it's how the spec defines it afaict

somber solar
#

just memory and cycles wasted

somber solar
#

learning menix

near tartan
near tartan
#

okay so i need to implement a buddy allocator now

#

the current one is bad

cyan nexus
#

same here lol

near tartan
#

finally

near tartan
#

@hoary cave progress

#

i made the decision to always ignore memory below 64KiB so i can do the trampoline shit without a worry in the world

near tartan
#

@hoary cave lfg

#

we are back

grave peak
#

What did you change?

near tartan
#

allocators

#

have my own now instead of using a crate

#

but it's still dying a little bit

grave peak
#

Ah letsgo

#

Is it still rust

near tartan
#

yes

grave peak
#

L but lfg

grave peak
#

Btw any udrm progress

#

Or is that paused

near tartan
#

on hold

#

i think its scope is way too big

#

and i know too little

#

as it turns out

grave peak
#

Its a huge project that's true

near tartan
#

i fixed the bug...

#

allocator works now

#

i accidentally didn't update the phys base of a region so it gave out the metadata as usable memory ๐Ÿ—ฟ

grave peak
#

No struct page skill issue

near tartan
#

yea now i can also handle kaslr hhdms

#

last step is doing deallocations

grave peak
#

Letsgo

near tartan
#

need to think of a way how to best do virtual memory allocations

#

right now i just have bump allocation

#

but that doesn't sound like a great idea

ionic lava
#

ok. why that environment is always "unsound"? I've already used to see this print, looking over screenshots here. Still have no idea what does it mean though.

near tartan
#

unsound means something like insecure#

#

like, something has messed up the state in a way that's not supposed to happen

ionic lava
#

I see, thanks. Is it rust related in this context or more general?

near tartan
#

just in general, but it is to say "something in unsafe code has caused wrong behavior"

#

@grave peak ooooooof

#

pain

#

to be fair, there's a shit ton of things still left to optimize here

#

i have to hook up my fast memcpy, the regular malloc impl just uses the physical allocator + hhdm (no caching whatsoever)

ionic lava
#

From 5,239,043 to 235,000. Was that number achieved with rust btw?

near tartan
#

5M was in C

#

235k is rust

#

but it's not because of rust

#

the entire code base is different

#

the allocator i have now is missing a lot

#

i'm sure once i add my slab allocation back in, this score is going to get much better

ionic lava
#

Genuinely interested to see the results between functionally on pair implementations in C and rust.

near tartan
#

i'm getting there

#

it'll take a week at least still

near tartan
#

i've replaced the rust mem* functions with my own (primitive) ones, and it's already a bit faster

#

the most part is still going to be the allocator

near tartan
#

bruh it triple faults on real hw

#

i think something is not mapped

#

I don't even get to the fbcon

#

i gotta check the mapping again

near tartan
#

it's actually not mapped

#

(this is with the limine pagetable)

grave peak
near tartan
#

okay nevermind

#

@grave peak kernel crashes because of something uacpi does

#

idk yet what exactly

#

but if i turn acpi off it doesn't triple fault

grave peak
#

99% your bug trl

near tartan
#

i didnt say it's an uacpi bug

#

just said that uacpi is doing something that's not nice to my interfaces

somber solar
#

me when fixed events are trying to execute from the stack

#

uacpi bug of course

grave peak
#

real and true

near tartan
#

it's probably a virt memory bug

#

fucking hell

#

wish i could debug with serial

#

i wonder what the issue is

#

yooo lets go i got access to a server with com1

#

lfg

near tartan
#

pog

near tartan
#

@grave peak lol?

[    0.000000] acpi: Initializing...
[    0.004574] acpi: FACS 0x00000000A890D000 00000040
[    0.097220] error: acpi: unable to attach (PCI_Config) operation region \_SB_.PC00.PMC1.PMCB: unimplemented
[    0.111672] error: acpi: aborting method invocation due to previous error: unimplemented
[    0.123506] error: acpi:     #0 in \PMB1()
[    0.128822] error: acpi: Op 0x5B80 ('OpRegionOp'): invalid argument type: Uninitialized, expected a Operand := TermArg => Integer
[    0.146356] error: acpi: aborting table load due to previous error: incompatible AML object type
[    0.159183] error: acpi:     #0 in \()
[    0.163971] error: acpi: failed to load 'DSDT' (OEM ID 'LENOVO' OEM Table ID 'THINKSYS'): incompatible AML object type
[    0.180268] error: Kernel panic - Environment is unsound!
[    0.187921] error: at kernel/src/generic/platform/acpi/uacpi.rs:63:56
[    0.196679] error: "called `Result::unwrap()` on an `Err` value: Utf8Error { valid_up_to: 26, error_len: Some(1) }"
#

whats going on here

grave peak
#

you dont have PCI

#

so everything fails

near tartan
#

why is your print function trying to print invalid data tho

grave peak
#

idk, more info needed

near tartan
#

idk one sec

#

this is where it panics

grave peak
#

whats the string that it prints

near tartan
#

not a valid c string apparently

grave peak
#

doubt

near tartan
#

could the allocator be to blame for this?

grave peak
#

if you give me a backtrace i could tell you

near tartan
#

the error means that after 26 characters it encountered a non utf-8 char

#

don't have that yet meme

#

that test machine is super flaky

#

but yes, it's probably my allocator

#

woe

grave peak
#

can u just remove the ascii char assert

#

and print it out

near tartan
#

it's not replicable ๐Ÿ’€

#

this only happened just now

#

osdev is schizo programming

grave peak
#

lol

near tartan
#

i need to put more asserts in my allocator

#

(and probably actually do slab allocation)

cyan nexus
pine rock
near tartan
#

whats that

#

and how is it better

pine rock
#

two level segregated fit allocation

#

and its got very good fragmentation, and has O(1) allocation and free

#

its what vulkanmemoryallocator and d3d12ma use as their internal allocator, so plenty of prior art

marble salmon
#

It's also not O(1)

#

Or am i missing something

pine rock
#

its O(1) if you use the good fit algorithm rather than exhaustive best fit

#

its a couple of bitmap tests and then either segmenting the null block or another free block

#

if you do best fit you walk the freelist for 1 or 2 buckets

near tartan
#

@grave peakup to 1mil again

#

oh wow yea this really is because i have no real malloc

#

using buddy allocation for that is bad it seems

grave peak
#

Nice

near tartan
#

i expect this to go up a lot

#

i ran with 128M

#

if i put e.g. 4G ram in qemu then performance tanks

near tartan
#

hell yea i just got access to a two socket thinkcentre

#

after i finish malloc I'm going to do smp spinup

#

that'll be fun

marble salmon
pine rock
#

how so?

marble salmon
#

it needs to walk the bucket list to find a non-empty bucket

#

that's O(number of buckets)

#

which is O(log n) if the buckets are exponentially in size

#

also, the experiments only compare against bad algorithms

#

the established theory and practice is that first fit (or algorithms similar to first fit) performs best in practice

#

so it'd be very surprising if this "buddy like" strategy outperforms first fit

#

they only compared against a first fit which walks the free list

#

which is just stupid

#

Also, the fragmentation properties are quite bad

#

this allocator can run OOM despite there being a large enough free chunk available

#

this can't happen with first fit

marble salmon
#

during allocation it only considers the bucket that has blocks that are guaranteed to be large enough for the allocation

#

but there may actually be large enough blocks in the next smaller bucket as well

near tartan
#

what allocator should i go with?

#

i was just sticking to slab

marble salmon
#

depends on what you mean by slab, there is not a single slab allocator design

#

mimalloc is an actually good algorithm and rather simple to implement

cyan nexus
#

way more flexible

pine rock
#

honestly unless you actually care about designing your own allocator i'd find a crate to do it for you

cyan nexus
#

...

#

why a crate?

near tartan
#

the ones i've tried are ass

#

they don't take in an underlying allocator

cyan nexus
#

btw, if you want you can see how mine works

pine rock
cyan nexus
#

it's pretty easy to understand

#

and you can allocate a flexible size

#

and it can request more pages if it needs + dealloc pages if not needed anymore

pine rock
#

theres no shame in not doing everything from scratch

near tartan
#

jesus christ ELF format

near tartan
#

something is dying very early during boot

#

before i get to init the fbcon

#

i might have to build an earlyfbcon that lives right until the switch to the kernel page table happens

#

without a backbuffer

#

i dont have serial on any machine sadly

idle flower
#

i have two machines with serial, one amd phanon x4? and one dell r730dx

near tartan
#

damn

idle flower
#

i just need a disk image or cd image

#

i hope that the ipmi interface passes through serial

#

keyboard passthrough didnt quite work last time i checked

#

i would have more if my father didnt throw out a lot of his machines a decade agonooo

#

like 8086 and up, nearly every major generation

#

up to athlon 64

near tartan
#

i have to add iso building to bootstrap

idle flower
idle flower
near tartan
#

it's 1gb big :(

#

unless you can build the image yourself

idle flower
#

i can try

near tartan
#

if you run install-minimal it'll only build the necessary stuff of the toolchain

#

but you could just get away with building limine + menix

idle flower
#

does it work on win11?

near tartan
#

wdym

#

you need wsl probably

#

it's containerized though

idle flower
#

To build the distribution you will need the following tools installed on your system:

A POSIX-compatible shell
GNU make
curl

To create a bootable image you will additionally need:

dosfstools (for mkfs.vfat)
e2fsprogs (for mkfs.ext2)
parted (for partitioning the image)
near tartan
#

sounds like wsl

hoary cave
#

you need native linux to run jinx

#

so there's that

#

wsl1 won't work

#

i don't think it emulated linux user namespaces

near tartan
#

bruh

hoary cave
#

sorry

#

native linux as in

#

wsl2 will do

#

lol

near tartan
#

lol

hoary cave
#

wsl1 is the syscall translation layer

#

wsl2 is native (in a vm)

near tartan
idle flower
#

Could you send me the image directly? Setting up WSL and stuff will take sometime

near tartan
#

sure

#

I'll add iso build support and send you one later

#

or @hoary cave could add iso support ๐Ÿฅบ

hoary cave
#

i'm building rust

#

i'm sorry but not rn

near tartan
#

worth a shot

#

i will steal the recipes for my own rust toolchain

hoary cave
#

i am doing linux sooo

#

probably not helpful

#

i mean it is still cross-compilation so ig

near tartan
#

the bootstrapping at least

#

i need to see what to do with actual patching

idle flower
#

Or make your build system portable, but that will probably take way longer than setting up wsl

near tartan
#

tell that to mint

idle flower
#

Nice discord lag, thought I continued my last message

near tartan
#

lol

idle flower
near tartan
#

no

#

jinx

spark surge
#

????

#

Jinx needs Linux

#

it's a hard dependency

#

WSL2 counts as Linux

#

if you're on macOS you can get yourself a linux VM and then run Jinx in there

near tartan
#

windows is a lost cause anyways

#

i should probably document tho that you can use wsl2

modern hamlet
#

what does it use that is linux only and no other unix-like

spark surge
#

no one uses WSL1 anymore anyways

modern hamlet
spark surge
#

well

near tartan
#

if you use wsl1 you're stupid

spark surge
#

of course it's objectively untrue, but like

near tartan
#

problem solved

spark surge
#

lol

spark surge
#

basically

#

if you want to do reproducibility and encapsulation in any reasonable way

#

you need to choose on an OS

modern hamlet
#

and i tried hyper-v as well and it sucks too

#

also Vmmem is a ram hog even if i don't use wsl at the moment

near tartan
#

i just dual boot windows meme

modern hamlet
#

indeed that is a good solution

#

i got a 2TB SSD recently, i have no more excuse to not consider installing linux

#

i just dont know which distro and i dont have much free time

spark surge
#

CachyOS

modern hamlet
#

what is that

#

why wouldnt i use a "mainstream" distro like debian

eternal wharf
#

cauchy os

near tartan
#

debian is balls

#

only outdated packages

modern hamlet
#

or maybe arch

spark surge
#

CachyOS is like #3 on distrowatch, i'd call it mainstream enough

modern hamlet
#

but im trying to lose weight not gain

near tartan
#

arch or opensuse is what I'd recommend

spark surge
hoary cave
#

because she runs debian 8

near tartan
#

erm actually she has tumbleweed

hoary cave
hoary cave
#
  thread 'main' panicked at /base_dir/.jinx-cache/cargo-home/registry/src/index.crates.io-1949cf8c6b5b557f/system-deps-7.0.3/src/lib.rs:966:94:
  TARGET x86_64-unknown-linux-mlibc is not a builtin target, and it could not be parsed as a valid triplet: Unrecognized environment: mlibc
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace```
near tartan
#

getting her to use that was a pain i wish upon nobody tho

hoary cave
#

FYM CHAD

#

WHY DOES THIS SHIT NOT WORK

near tartan
#

system-deps

#

wtf

#

wait that's pkg-config memes

hoary cave
#

yeah but it uses cfg-expr to try and parse the target

#

and it fails because cfg-expr doesn't know about our target lol

#

this shit's so annoying

near tartan
#

a billion patches to do the same thing

#

love to see it

#

great ecosystem

hoary cave
#

that's the pain of not being upstream

#

crazy

near tartan
#

how does being upstream fix this?

#

i thought this is a 3rd party thing

hoary cave
#

yeah, upstream there

#

lol

near tartan
#

๐Ÿ—ฟ

idle flower
#

I will probably use rust build.rs as a buildsystem, truly portable and you need a rusttoolchain anyway if you want to compile the code os yourself

pine rock
#

i still build everything from source anyway though lol

near tartan
#

cringe

#

instead of just using a rolling distro

pine rock
#

i should just use gentoo tbh

near tartan
#

tbh you should try opensuse

#

#paidshill

#

what a good way to manage virtual memory allocations? do i just reuse my phys allocator?

#

how i feel rn

pine rock
#

but to start with im sure its fine

near tartan
#

okay i hacked in a super early fb console

#

lets see what's happening...

#

?????????

#

wtf do you mean level out of range

idle flower
#

me still waiting for the iso

near tartan
#

damn

#

i dont know how xorriso works woe

idle flower
#

nah no stress

near tartan
#

i can send an image tho

#

ill xz it

idle flower
#

if necesarry i can download it to my nas, ~7TB free

near tartan
#

if it dies without printing anything to serial do com1=no on the cmdline

idle flower
#

nice windows can extract xz compressed stuff

near tartan
#

install 7z

idle flower
#

well it worked out of the box

near tartan
#

oh you said can

#

i read can't

idle flower
#

yea its late

#

will test tomorror around ~10:00

#

is limine configured as autostart?

near tartan
#

yes

idle flower
#

like start selected entry after x seconds?

near tartan
#

yes

#

timeout is 5 sec

idle flower
#

could you send a image without autostart?

#

oh nice right on the day switch

#

with the last image i had lying around limine ignored the keyboard and just autostarted which prevented me from figuring it out how to pass through the keyboard

near tartan
#

WAIT NO

#

NON ONONONONONONOONON

#

PLEASE DONT TELL ME THIS IS A FUCKING ZEROING ISSUE

#

๐Ÿ’” brooooo

near tartan
#

i probably don't zero allocated physical memory...

cyan nexus
#

oof

near tartan
#

that's why the page tables get corrupted on real hw but not qemu

cyan nexus
#

why on real hw yes but not qemu?

near tartan
#

because qemu probably zeroes memory itself

#

im going to use limines randomize memory function to test this

cyan nexus
#

ah

#

i memset my mem to 0 when i alloc and even free stuff

near tartan
#

duh

#

i should too

#

HAHAHAHAHAHAH YES

#

IT'S ACTUALLY THAT

cyan nexus
#

lol

distant cypress
#

I have a flag that I pass to the page allocator (__ALLOC_ZERO) that if set, causes alloc_page to memset it to zero upon allocation.

near tartan
#

at last

#

it boots...

cyan nexus
#

add this to the limine cfg

near tartan
#

?

cyan nexus
#

it will randomize the mem as it would be on a real machine

near tartan
#

i already have

cyan nexus
#

oh

#

then how did it not bug out XD

near tartan
#

because i fixed it KEKW

cyan nexus
#

did you enable it after the fix?

near tartan
#

yes

cyan nexus
#

oh

#

lol

near tartan
#

hm it doesn't even get to the early fb on my framework though...

#

the only thing i can think of is the serial code blocking infinitely

cyan nexus
#

gdb time

near tartan
#

yes it was indeed serial

cyan nexus
#

lol

near tartan
#

hell yes

#

we are back again

cyan nexus
#

cool

#

btw, how much slower is the boot with the randomize mem on?

near tartan
#

A LOT

cyan nexus
#

oof

near tartan
#

takes a solid minute

cyan nexus
#

how much ram?

near tartan
#

both devices have 64gb of ddr5

cyan nexus
#

oh, 64gb

#

yeah, that takes a lot

near tartan
#

bruh the ryzen 7700 doesn't have x2apic

#

i need to do regular apic support anyways

cyan nexus
#

i still need to understand how to correctly init APICs and X2APICs

near tartan
#

this is my brothers pc

grave peak
near tartan
#

framework moment

grave peak
near tartan
#

i can try on that proliant and think station

#

they all have ipmi and bmc control

grave peak
#

if you dont have numa support multisocket will be slow af tho

near tartan
#

I don't have smp yet anyways

#

the new allocator can give out 16-bit memory

#

i wonder how aids x86 smp actually is

#

the setup at least

grave peak
#

its pretty good

near tartan
#

what's the procedure?

#
  • load trampoline in 16 bit memory
  • self ipi?
grave peak
#

why self?

near tartan
#

or like

grave peak
#

ipi the cpu u want to wake

distant cypress
distant cypress
# near tartan what's the procedure?
  1. you load the trampoline somewhere in the lower 1MiB of memory.
    for each CPU:
  2. INIT level assert
  3. a very tiny microsecond delay
  4. INIT level deassert
  5. another very tiny microsecond delay
  6. send SIPI(vector=trampoline addr>>12), this is why it has to be in the lower 1MiB
  7. loop until the CPU says it is online or some number of microseconds have passed
  8. repeat 6 and 7 once
  9. if the CPU doesn't say it is online, SMP bringup failed
near tartan
#

what's that init level assert?

distant cypress
#

INIT IPI with trigger mode level

#

iirc

cyan nexus
#

with limine it's even simpler

near tartan
#

I don't want to use limine smp

distant cypress
#

yeah we know

cyan nexus
near tartan
#

i also want to support other protocols so ic can't rely on that

cyan nexus
#

how do you tell the other cpus the trampoline location btw

distant cypress
#

the "correct" thing to do is to refer to whatever the old Intel MP specification says. the sane thing to do is to refer to Linux sources

near tartan
distant cypress
fiery marlin
#

the sdms also document how you're supposed to start the APs

near tartan
#

will look at that

#

do you happen to know which volume?

#

i have the amd64 manual in book form

distant cypress
#

I'm pretty sure there are slight differences between modern AMD and Intel, but the old Intel MP stuff should work on both.

near tartan
#

probably this one

#

found it

grave peak
#

damn

near tartan
#

i have obtained a souvenir

full topaz
near tartan
#

that did not work out as intended

#

๐Ÿ’” why is it so slow

#

my old slab impl was fucked

grave peak
near tartan
#

fyi this was the worst scenario i could be in

#

kvm off, debugger on, unoptimized debug build, slab allocator allocates page wise with buddy alloc as a backing allocator

grave peak
#

Lol

near tartan
#

:)))))))))))))))))))))))))

#

thanks rust for catching this at least

near tartan
#

okay that's MUCH better

#

still much more shit than before

#

sadge

#

okay now the module loader fails for some reason???

#

cant find symbols

#

ok bro

#

this speed kinda sucks :(

#

wonder if it's actually because i used a bitmap before

#

not another allocator issue....

storm bobcat
near tartan
#

idk what it is

#

most likely actually the buddy allocator

#

that's the only thing that's different from the C version

fiery marlin
#

Oh lol

near tartan
#

FUCKING RUST

#

OMFG WHO DOES THAT

#

KEEP YOURSELF SAFE BRO

#

@grave peak I'M GETTING SOMEWHERE

#

i can optimize this a lot still

#

time to write phd memcpy/set impls

grave peak
#

Nice

idle flower
near tartan
#

you can find them on the remove-talc branch

#

kernel/src/generic/memory/libc.rs

idle flower
#

Nice

#

I will try to use mimalloc in my kernel, hopefully it's faster than alternatives

#

I'm still sitting at the basics

#

Jumping between them each time I discover that a previous assumption was wrong/suboptimal

#

At least the spinlocks look solid

#

Until I have to debug them at least

storm bobcat
grave peak
#

Proxima malloc is 200 lines and takes 100ns per allocation

#

All it requires is a struct page

storm bobcat
grave peak
#

TSC

#

and compiler magic

#

there's a guide pinned in uacpi

fickle elbow
#

data structure?

fickle elbow
grave peak
#

i dont understand the question

near tartan
#

data structure

grave peak
#

structured data

fickle elbow
#

how do you keep track of allocated memory

grave peak
#

just a field in struct page

near tartan
grave peak
near tartan
#

seems like github scans cargo files

#

i use talc atm for allocations, but it lacks support for an underlying allocator

grave peak
#

ah

near tartan
#

and if i split up the phys allocation to use my own allocator, then i'm going to have some issues with that

#

there is a wip branch which adds that

near tartan
#

i may actually be stupid

#

instead of trying to atomically load a thread pointer i can just get the thread id atomically and use that to get the thread pointer

#

right?

idle flower
#

more context needed

near tartan
#

also i should probably just make my own spinlock primitives

idle flower
#

mine should be on github

#

but they are ticket based

#

as i never plan to have queued threads > hardware threads

#

else the ticket approach fails spectacular

#

as you cant preemt the thread

#

except for independent very short interrupts like msi interrupts

#

my locks should work โ„ข๏ธ

#

they are untestedtrl

#

well i tested them in my head

near tartan
#

is it?

grave peak
#

in my old kernel i just loaded lapic id and then indexed by it in the array lol

grave peak
near tartan
#

well sure, but wouldn't i have to do locking anyways while i work on the thread data

grave peak
#

depends what u need from the data

#

u can just preempt_disable() before

near tartan
#

preempt disable as in cli?

grave peak
#

it can be that if u want

#

but no, most of the time it just prevents preemption but not interrupts

#

in nt terms that would be a raiseirql

#

to dispatch or higher

fiery marlin
fiery marlin
#

Ah lol

grave peak
#

no shame in just disabling preemption

#

it can be a simple refcounter and an if check in schedule()

#

and in preempt_enable() just go into schedule() if refcount is now 0

autumn jasper
#

there is shame

grave peak
#

rust copium trl

near tartan
#

i mean i can store a raw Rc in the percpu struct

#

which gets assembled/disassembled by the scheduler

near tartan
#

it's a learning experience after all

#

i don't write a kernel because i think it'll be usable/successful

grave peak
#

yeah im just internally accumulating reasons as for why rust shouldnt be used as a systems language trl

autumn jasper
grave peak
#

u can have a preempt pending bit if u want to be fancy

near tartan
autumn jasper
#

my apologies im trying to learn to be more diplomatic

#

Your provided solution is known to be suboptimal

grave peak
autumn jasper
#

yeah

#

essentially

#

per-cpu bit that says "the current thread has been preempted but this was deferred due to preempt_disable"

grave peak
#

yeah basically if your timer irq "tried" to preempt you but couldnt because you're in a preempt_disable it can set this bit basically

#

which is how most people do it i think

near tartan
#

ah

autumn jasper
#

like a higher priority thread being readied (unblocked) by an io completion interrupt

grave peak
#

yea

near tartan
#

i think i can use this

#

then just store the thread pointer directly in the percpu block

hoary cave
#

yes you can

#

i told you about that

near tartan
#

eh it should be fine

#

how does the Arc even do the conversion

hoary cave
#

it does inner + sizeof(Inner) for into_raw

#

and from_raw does ptr - sizeof(Inner)

#

or, well

#

inner structure of Arc is

struct {
  Rc rc;
  T data;
}```
#

so, really, all it's returning is a pointer to your data

near tartan
#

ah

hoary cave
#

and from_raw just does container_of

near tartan
#

100% from_raw is unsafe then, right?

#

makes sense

hoary cave
#

yeah it is, of course

near tartan
#

i can live with that

hoary cave
#

into_raw keeps the ref count alive so as long as you have a matching from_raw it's fine

near tartan
#

perfect

#

i think this friday/weekend it's finally scheduler + async time

hoary cave
#

async?? holy

near tartan
#

ye

#

i'll make a task spawner that plays right into the normal scheduler

hoary cave
#

it doesn't make a whole lot of sense to treat futures as full blown kernel tasks

#

they don't need their own register state etc.

#

but i'm not sure how it should be done so idk why i even talk ๐Ÿ’€

near tartan
#

idk either

#

lol

#

well i think i can allocate a worker thread per irq?

#

then just have an irqaction defer to a future

#

or idk

hoary cave
#

async is rust is pretty funny

#

do you have any idea how it works? or none at all

#

i still don't know how it works fully but i do have some idea since i worked with it when writing the hel bindings

near tartan
#

with smol

hoary cave
#

well, i'm talking about all the language elements, not about writing async code

#

Future, Waker etc

#

well, the Waker interface is pretty funny

near tartan
#

nah no idea

hoary cave
#

actually idk if rust async in kernel will be good

#

i wonder if you can get away without most of the allocations

#

it's kinda annoying you need at least an allocation per future but idk if any other language does it better

near tartan
#

trying to see if it's feasible

#

if it doesn't work out ill just drop it

hoary cave
#

one thing i know is a bit shitty is that they don't get an AsyncDrop or anything similar

#

which sucks if you have resource clean up that needs to be async

#

but it's not really something that only sucks in-kernel, also sucks in userspace

near tartan
#

rfc when

idle flower
#

i can send you my design for thread/core local stuff

near tartan
#

do

hoary cave
#

DO.

autumn jasper
#

What do you want to use async rust for in your kernel

near tartan
#

idk

#

surely there's a use for it?

autumn jasper
#

Doubt it

near tartan
#

async io or something like that

hoary cave
#

managarm uses async in kernel

#

they don't do it for no reason

idle flower
#

pub struct CoreLocalPointer();

impl Deref for CoreLocalPointer {
    type Target = CoreLocalData;

    fn deref(&self) -> &CoreLocalData {
        unsafe { &*cpu::get_cl_pointer() }
    }
}

impl DerefMut for CoreLocalPointer {
    fn deref_mut(&mut self) -> &mut CoreLocalData {
        unsafe { &mut *cpu::get_cl_pointer() }
    }
}

pub struct CoreLocalData {
    pub(super) arch_data: [u8; 64], //TODO move it into a concrete type definded in arch::*
    pub core_id: u64,
    pub core_csprng: CSPRNG,
    pub system_plm_offset: VirtLv1PageAddress,
    pub process_plm_offset: VirtLv1PageAddress, //Move to a dedicated struct later
    pub global_data: Arc<GlobalData>,
    pub thread_data: TlsData,
    //pub process_data
}

impl Drop for CoreLocalData {
    fn drop(&mut self) {
        panic!("Undroppable Value Dropped")
    }
}

pub struct TlsData {
    pub process_id: u32,
    pub local_heap: ProcessNumaHeapAllocator,
    pub held_locks: AtomicUsize,
    pub yield_to_scheduler: AtomicBool,
    pub current_plm_offset: VirtLv1PageAddress,
}

#

maybe i should wrap TlsData wit Arc<> tbh
but TlsData isnt supposed to be accessed from outside the owning thread

near tartan
#

i have a different approach to percpu data

#

i do what managarm does

autumn jasper
near tartan
#

they do

#

oh well no they dont im stupid

#

but in the servers

eternal wharf
#

i mean if you grep for co_await you'll find it in the kernel as well

hoary cave
#

using rust async wouldn't make a lot of sense given the kernel is not written in rust

autumn jasper
#

yes

#

and also because it does implicit allocations

hoary cave
#

glad we agree

autumn jasper
#

which is what i was actually talking about

near tartan
#

hm

hoary cave
#

implicit allocations?

#

i didn't know that

near tartan
#

when?

hoary cave
#

i thought all the allocations you needed was the Box around the future if you want to store it since it's a trait

idle flower
#

afaik Rust explicitly doesnt do implicit allocations for a lot of things including Futures

near tartan
#

@hoary cave didnt you say that there's no asyncdrop?

hoary cave
#

i don't think there is

hoary cave
#

yo wtf

#

it's a nightly only api though

near tartan
#

is that an rfc?

hoary cave
#

behind a feature flag

near tartan
#

ok and

#

we are on nightly

hoary cave
#

pretty new

#

also, pretty unfinished

near tartan
#

hm

hoary cave
#

idk if that will work very well but you are free to try

near tartan
#

so safe to say it's shit

#

i dont even know if i actually want async in the kernel

hoary cave
#

but it seems to be an accepted feature that's being worked on

near tartan
#

seems like its a bad idea

hoary cave
#

async has its uses and drawbacks

#

that's all i can say

autumn jasper
hoary cave
#

idk if it's a good choice for kernel code

near tartan
#

in a kernel context, most things are "async" by definition

#

like irq handlers

#

so if that works with normal functions I don't see the need

#

seems like a pointless abstraction

near tartan
#

how should i store struct pages for multiple memory regions? do i have an array per memory region or just store one big array (even if it contains holes)?

#

like, if there's some huge holes in memory between two usable regions, how do i represent that?

hoary cave
near tartan
#

oh duh I'm stupid

#

could've thought of that

#

so i assume i would also need an allocator for virtual memory, right?

hoary cave
#

maybe, this "big array" can just be statically placed somewhere

near tartan
#

hm

hoary cave
#

i don't think you can allocate memory without a physical allocator first though

near tartan
#

yes

#

the question is then, how to do that

hoary cave
#

just place this array statically in virtual memory

#

just like the hhdm is

near tartan
#

so at a fixed address like 0xffff_9000_0000_0000?

hoary cave
#

sure

#

that might be too close to the hhdm

#

but yeah thats the spirit

near tartan
#

hm

#

i could just say "align to the next pd"

hoary cave
#

yeah, well, the problem is also aligning the memory for page tables i guess

near tartan
#

hm?

#

what i could do is having a bootstrap page table with the single purpose of building the actual kernel page table

#

e.g. in the limine-specific init code

#

hm that's getting quite close to having an eir-ish prekernel

hoary cave
#

it's not limine specific

#

the hhdm, or the page struct array

near tartan
#

the hhdm is pretty much limine specific

hoary cave
#

well, yes, but do you want to map any memory you access in your kernel manually?

#

for certain things it's easier to access physical memory through a direct memory map

near tartan
#

not wrong

#

so what's wrong with just saying "give me the next pt top level entry"

hoary cave
#

you need to allocate the page tables needed when mapping the page array

near tartan
#

but this is a calculation i can do beforehand, right?

hoary cave
#

maybe, but i don't think it's so simple

#

you might wanna map some of that memory using 2MiB pages

#

i guess it is a pretty simple calculation after all

#

maybe i was overthinking it

near tartan
#

as i understand it, i just subtract the amount of pages needed to build the pt from a region with free memory?

#

or what are you thinking of

hoary cave
#

the amount of pages needed to build the page tables + the amount of memory needed for the page array itself

near tartan
#

ah yes

#

but that should be fine

hoary cave
#

keep in mind 2MiB pages need to be 2MiB aligned

near tartan
#

i can determine if i can do a 2mb region

#

yes

hoary cave
#

that slightly complicates the process of reserving memory

near tartan
#

how so

hoary cave
#

because it's annoying, assuming you can either "skip" over the non-2MiB aligned memory in the free entry in which case you basically throw away a lot of memory, or do what i did in my shitty kernel, which is ugly

near tartan
#

hm

#

and i can't map unaligned memory with 4k until i have 2M alignment?

hoary cave
#

you can, but you're wasting memory

#

you need to allocate a quite a few page tables you otherwise wouldn't have to

near tartan
#

ah true

#

that'd be one additional page per unaligned 2M region, right?

hoary cave
#

yes, but it doesn't guarantee you'll end up with 2MiB alignment afterwards

#

what i think is the best way to do this is

#

let me write some code for that

#

pseudo code of course

#
typedef struct { bootstrap_page *next } bootstrap_page_t;

bootstrap_page_t *first_4kib = NULL;
bootstrap_page_t *first_2mib = NULL;

#define LIST_PUSH(head, item)        \
    do {                \
        item->next = *(head);    \
        *(head) = item;        \
    } while(0)

void do_the_thing(memory_entry_t *entry) {
    for(size_t i = 0; i < entry->length;) {
        uintptr_t addr = entry->base + i * PAGE_SIZE;
        bootstrap_page *page = (bootstrap_page *)addr;
        if(is_aligned(addr, PAGE_SIZE_2MIB)) {
            LIST_PUSH(&first_2mib, page);
            i += PAGE_SIZE_2MIB;
        }else{
            LIST_PUSH(&first_4kib, page);
            i += PAGE_SIZE;
        }
    }
}

do_the_thing(biggest_entry);
do_the_thing(second_biggest_entry);
#

you could just have this bootstrap discount buddy allocator before you initialize your actual physical memory allocator

#

sort them into two buckets, 4KiB and 2MiB

#

if you run out of 4KiB pages you can take a 2MiB one and split it up into 4KiB pages

#

or you could do what managarm does, initialize a buddy allocator with all of your physical memory in eir, use it to allocate whatever you need and just pass through the buddy allocator structures to thor

near tartan
#

a prekernel could work

hoary cave
#

you don't necessarily need a prekernel for that

near tartan
#

like an init function then?

hoary cave
#

good question, i have no clue how to nicely do this, sorry

#

i guess you could split your physical allocator into two parts

near tartan
#

lol

hoary cave
#

the buddy allocator that you could initialize early that handles handing out physical addresses and the one that hands out struct pages

fiery marlin
#

you can do a bump allocator over the memory map for early physical allocations

hoary cave
#

but no clue if that's good or not

fiery marlin
#

since you're unlikely to free any of it

#

same goes for virtual allocations

#

you're not going to reclaim memory/address space used by struct page and co

hoary cave
#

we want to be able to do 2MiB aligned physical allocations