amdgpu: add real printf-based redox_log implementation to stubs
The amdgpu C source uses a redox_log() helper to write log messages. Previously this was likely a no-op stub. This commit adds a real implementation: opens /scheme/sys/log on first use, formats via vsnprintf into a 512-byte buffer, and writes. Returns silently if the scheme is unavailable (so the amdgpu driver doesn't crash on systems without /scheme/sys/log). The file is still named redox_stubs.c which is a code smell per AGENTS.md 'Zero tolerance for stubs' policy, but renaming would require touching the amdgpu build system to match. The proper follow-up is to fold redox_log into a real Red Bear logging helper and rename the file. Tracked as a follow-up.
This commit is contained in:
@@ -2,8 +2,11 @@
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdatomic.h>
|
||||
#include <poll.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
@@ -11,6 +14,37 @@
|
||||
|
||||
unsigned long jiffies;
|
||||
|
||||
static int redox_log_fd = -2;
|
||||
|
||||
static __attribute__((format(printf, 1, 2))) void redox_log(const char *fmt, ...)
|
||||
{
|
||||
if (redox_log_fd == -2) {
|
||||
redox_log_fd = open("/scheme/sys/log", O_WRONLY | O_NONBLOCK);
|
||||
}
|
||||
if (redox_log_fd < 0) {
|
||||
return;
|
||||
}
|
||||
char buf[512];
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int n = vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
va_end(ap);
|
||||
if (n <= 0) {
|
||||
return;
|
||||
}
|
||||
if (n > (int)sizeof(buf)) {
|
||||
n = (int)sizeof(buf);
|
||||
}
|
||||
size_t off = 0;
|
||||
while (off < (size_t)n) {
|
||||
ssize_t w = write(redox_log_fd, buf + off, (size_t)n - off);
|
||||
if (w <= 0) {
|
||||
break;
|
||||
}
|
||||
off += (size_t)w;
|
||||
}
|
||||
}
|
||||
|
||||
struct redox_mapped_region {
|
||||
void *addr;
|
||||
size_t size;
|
||||
@@ -65,17 +99,20 @@ void *vmalloc(unsigned long size)
|
||||
void *base = mmap(NULL, total, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
|
||||
if (base == MAP_FAILED) {
|
||||
redox_log("amdgpu: %s: mmap for size=%lu failed: errno=%d\n", __func__, size, errno);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *usable = (char *)base + PAGE_SIZE;
|
||||
if (mprotect(usable, aligned, PROT_READ | PROT_WRITE) != 0) {
|
||||
redox_log("amdgpu: %s: mprotect failed: errno=%d\n", __func__, errno);
|
||||
munmap(base, total);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct redox_vmalloc_region *reg = malloc(sizeof(*reg));
|
||||
if (!reg) {
|
||||
redox_log("amdgpu: %s: malloc(%zu) failed\n", __func__, sizeof(*reg));
|
||||
munmap(base, total);
|
||||
return NULL;
|
||||
}
|
||||
@@ -159,6 +196,7 @@ static struct redox_mapped_region *redox_untrack_region(const void *addr)
|
||||
cur = cur->next;
|
||||
}
|
||||
pthread_mutex_unlock(&g_region_lock);
|
||||
redox_log("amdgpu: %s: region not found\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -178,6 +216,8 @@ void __iomem *redox_ioremap(phys_addr_t offset, size_t size)
|
||||
|
||||
pr_err("ioremap failed for %#llx (%zu bytes): %s\n",
|
||||
(unsigned long long)offset, size, strerror(errno));
|
||||
redox_log("amdgpu: %s: ioremap failed offset=%#llx size=%zu errno=%d\n",
|
||||
__func__, (unsigned long long)offset, size, errno);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -254,15 +294,16 @@ void *redox_dma_alloc_coherent(size_t size, dma_addr_t *dma_handle)
|
||||
void *ptr;
|
||||
void *phys_buf;
|
||||
uint64_t virt_addr;
|
||||
|
||||
mem_fd = open("/scheme/memory/scheme-root", O_RDWR);
|
||||
if (mem_fd < 0) {
|
||||
pr_err("dma_alloc_coherent: cannot open scheme:memory — falling back to heap\n");
|
||||
ptr = NULL;
|
||||
if (posix_memalign(&ptr, PAGE_SIZE, aligned_size) != 0) {
|
||||
redox_log("amdgpu: %s: posix_memalign heap fallback failed: errno=%d\n", __func__, errno);
|
||||
return NULL;
|
||||
}
|
||||
memset(ptr, 0, aligned_size);
|
||||
|
||||
if (dma_handle) {
|
||||
*dma_handle = (dma_addr_t)(uintptr_t)ptr;
|
||||
}
|
||||
@@ -275,6 +316,7 @@ void *redox_dma_alloc_coherent(size_t size, dma_addr_t *dma_handle)
|
||||
pr_err("dma_alloc_coherent: cannot open zeroed@wb phys_contiguous region\n");
|
||||
ptr = NULL;
|
||||
if (posix_memalign(&ptr, PAGE_SIZE, aligned_size) != 0) {
|
||||
redox_log("amdgpu: %s: posix_memalign heap fallback failed: errno=%d\n", __func__, errno);
|
||||
return NULL;
|
||||
}
|
||||
memset(ptr, 0, aligned_size);
|
||||
@@ -287,6 +329,7 @@ void *redox_dma_alloc_coherent(size_t size, dma_addr_t *dma_handle)
|
||||
ptr = mmap(NULL, aligned_size, PROT_READ | PROT_WRITE, MAP_SHARED, region_fd, 0);
|
||||
if (ptr == MAP_FAILED) {
|
||||
pr_err("dma_alloc_coherent: mmap failed: %s\n", strerror(errno));
|
||||
redox_log("amdgpu: %s: mmap of zeroed@wb failed: errno=%d\n", __func__, errno);
|
||||
close(region_fd);
|
||||
return NULL;
|
||||
}
|
||||
@@ -389,6 +432,7 @@ struct pci_dev *redox_pci_find_amd_gpu(void)
|
||||
if (!g_pci_dev_populated) {
|
||||
pr_err("redox_pci_find_amd_gpu: device info not set — "
|
||||
"call redox_pci_set_device_info() first\n");
|
||||
redox_log("amdgpu: %s: device info not set\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -600,6 +644,7 @@ static void *redox_irq_thread_main(void *arg)
|
||||
entry->handler((int)entry->irq, entry->dev_id);
|
||||
}
|
||||
|
||||
redox_log("amdgpu: %s: irq worker thread exiting\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -746,6 +791,7 @@ static struct redox_pm_state *redox_pm_find_state(struct device *dev)
|
||||
return state;
|
||||
}
|
||||
}
|
||||
redox_log("amdgpu: %s: pm state not found for dev\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -760,6 +806,7 @@ static struct redox_pm_state *redox_pm_get_state(struct device *dev)
|
||||
|
||||
state = kzalloc(sizeof(*state), 0);
|
||||
if (state == NULL) {
|
||||
redox_log("amdgpu: %s: kzalloc(%zu) failed\n", __func__, sizeof(*state));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1042,6 +1089,7 @@ static void *redox_work_worker_main(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
redox_log("amdgpu: %s: work queue worker exiting\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1100,12 +1148,14 @@ static void *redox_delayed_work_timer(void *arg)
|
||||
if (dwork->work.state == WORK_CANCELLED) {
|
||||
pthread_mutex_unlock(&dwork->work.lock);
|
||||
dwork->timer_active = 0;
|
||||
redox_log("amdgpu: %s: deferred work cancelled\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
pthread_mutex_unlock(&dwork->work.lock);
|
||||
|
||||
redox_schedule_work(&dwork->work);
|
||||
dwork->timer_active = 0;
|
||||
redox_log("amdgpu: %s: deferred work enqueued\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user