dde_linux: eliminate global ctors in lx_kit

As the lx_kit library is used by the vfs_lxip plugin, it must not
contain any static global constructor.

Related to issue #3487
This commit is contained in:
Norman Feske 2019-09-24 11:30:43 +02:00 committed by Christian Helmuth
parent c8b7710e5d
commit 90a91f3536
19 changed files with 206 additions and 52 deletions

View File

@ -388,8 +388,15 @@ static inline u64 get_jiffies_64(void) { return jiffies; }
#include <lx_emul/spinlock.h>
#include <lx_emul/semaphore.h>
#include <lx_emul/mutex.h>
LX_MUTEX_INIT_DECLARE(bridge_lock);
LX_MUTEX_INIT_DECLARE(core_lock);
#define bridge_lock LX_MUTEX(bridge_lock)
#define core_lock LX_MUTEX(core_lock)
static inline int mutex_lock_interruptible(struct mutex *lock) {
mutex_lock(lock);

View File

@ -60,6 +60,9 @@ struct Main
Lx_kit::construct_env(env);
LX_MUTEX_INIT(bridge_lock);
LX_MUTEX_INIT(core_lock);
/* init singleton Lx::Scheduler */
Lx::scheduler(&env);

View File

@ -145,6 +145,13 @@ size_t iov_iter_count(struct iov_iter *i);
container_of(callback_timer, typeof(*var), timer_fieldname)
#include <lx_emul/mutex.h>
LX_MUTEX_INIT_DECLARE(mdio_board_lock);
LX_MUTEX_INIT_DECLARE(phy_fixup_lock);
#define mdio_board_lock LX_MUTEX(mdio_board_lock)
#define phy_fixup_lock LX_MUTEX(phy_fixup_lock)
#include <lx_emul/bitops.h>
#include <lx_emul/atomic.h>
#include <lx_emul/work.h>

View File

@ -56,6 +56,9 @@ struct Main
Lx_kit::construct_env(env);
LX_MUTEX_INIT(mdio_board_lock);
LX_MUTEX_INIT(phy_fixup_lock);
/* init singleton Lx::Scheduler */
Lx::scheduler(&env);

View File

@ -563,6 +563,22 @@ void *kmalloc_array(size_t n, size_t size, gfp_t flags);
#include <lx_emul/mutex.h>
LX_MUTEX_INIT_DECLARE(hid_open_mut);
LX_MUTEX_INIT_DECLARE(host_cmd_pool_mutex);
LX_MUTEX_INIT_DECLARE(input_mutex);
LX_MUTEX_INIT_DECLARE(usb_bus_list_lock);
LX_MUTEX_INIT_DECLARE(usb_port_peer_mutex);
LX_MUTEX_INIT_DECLARE(usbfs_mutex);
LX_MUTEX_INIT_DECLARE(wacom_udev_list_lock);
#define hid_open_mut LX_MUTEX(hid_open_mut)
#define host_cmd_pool_mutex LX_MUTEX(host_cmd_pool_mutex)
#define input_mutex LX_MUTEX(input_mutex)
#define usb_bus_list_lock LX_MUTEX(usb_bus_list_lock)
#define usb_port_peer_mutex LX_MUTEX(usb_port_peer_mutex)
#define usbfs_mutex LX_MUTEX(usbfs_mutex)
#define wacom_udev_list_lock LX_MUTEX(wacom_udev_list_lock)
int mutex_lock_interruptible(struct mutex *m);

View File

@ -106,6 +106,14 @@ void start_usb_driver(Genode::Env &env)
/* initialize USB env */
Lx_kit::construct_env(env);
LX_MUTEX_INIT(hid_open_mut);
LX_MUTEX_INIT(host_cmd_pool_mutex);
LX_MUTEX_INIT(input_mutex);
LX_MUTEX_INIT(usb_bus_list_lock);
LX_MUTEX_INIT(usb_port_peer_mutex);
LX_MUTEX_INIT(usbfs_mutex);
LX_MUTEX_INIT(wacom_udev_list_lock);
/* sets up backend alloc needed by malloc */
backend_alloc_init(env, env.ram(), Lx_kit::env().heap());

View File

@ -34,8 +34,18 @@ typedef int clockid_t;
#include <lx_emul/timer.h>
#include <lx_emul/spinlock.h>
#include <lx_emul/mutex.h>
LX_MUTEX_INIT_DECLARE(dquirks_lock);
LX_MUTEX_INIT_DECLARE(input_mutex);
LX_MUTEX_INIT_DECLARE(wacom_udev_list_lock);
#define dquirks_lock LX_MUTEX(dquirks_lock)
#define input_mutex LX_MUTEX(input_mutex)
#define wacom_udev_list_lock LX_MUTEX(wacom_udev_list_lock)
typedef __u16 __le16;
typedef __u32 __le32;
typedef __u64 __le64;

View File

@ -270,6 +270,11 @@ Driver::Driver(Genode::Env &env) : env(env)
Genode::log("--- USB HID input driver ---");
Lx_kit::construct_env(env);
LX_MUTEX_INIT(dquirks_lock);
LX_MUTEX_INIT(input_mutex);
LX_MUTEX_INIT(wacom_udev_list_lock);
Lx::scheduler(&env);
Lx::malloc_init(env, heap);
Lx::timer(&env, &ep, &heap, &jiffies);

View File

@ -437,6 +437,16 @@ void *kmalloc_array(size_t n, size_t size, gfp_t flags);
#include <lx_emul/mutex.h>
LX_MUTEX_INIT_DECLARE(init_usb_class_mutex);
LX_MUTEX_INIT_DECLARE(usb_bus_idr_lock);
LX_MUTEX_INIT_DECLARE(usb_port_peer_mutex);
LX_MUTEX_INIT_DECLARE(usbfs_mutex);
#define init_usb_class_mutex LX_MUTEX(init_usb_class_mutex)
#define usb_bus_idr_lock LX_MUTEX(usb_bus_idr_lock)
#define usb_port_peer_mutex LX_MUTEX(usb_port_peer_mutex)
#define usbfs_mutex LX_MUTEX(usbfs_mutex)
/*******************
** linux/rwsem.h **

View File

@ -69,6 +69,11 @@ static void start_usb_driver(Genode::Env &env)
/* initialize USB env */
Lx_kit::construct_env(env);
LX_MUTEX_INIT(init_usb_class_mutex);
LX_MUTEX_INIT(usb_bus_idr_lock);
LX_MUTEX_INIT(usb_port_peer_mutex);
LX_MUTEX_INIT(usbfs_mutex);
/* sets up backend alloc needed by malloc */
backend_alloc_init(env, env.ram(), Lx_kit::env().heap());

View File

@ -3,6 +3,7 @@
* \author Norman Feske
* \author Sebastian Sumpf
* \author Josef Soentgen
* \author Christian Helmuth
* \date 2014-08-21
*
* Based on the prototypes found in the Linux kernel's 'include/'.
@ -29,9 +30,26 @@ struct mutex
};
#define DEFINE_MUTEX(mutexname) \
struct mutex mutexname; \
static void __attribute__((constructor)) mutex_init_ ## mutexname(void) \
{ mutex_init(&mutexname); }
struct mutex lx_mutex_ ## mutexname; \
void lx_mutex_init_ ## mutexname(void) \
{ mutex_init(&lx_mutex_ ## mutexname); }
/*
* Note, you must define a rename for 'mutexname' in lx_emul.h and explicitly
* call the LX_MUTEX_INIT() initializer on startup.
*
* lx_emul.h:
*
* LX_MUTEX_INIT_DECLARE(mutexname)
* #define mutexname LX_MUTEX(mutexname)
*
* lx_emul.cc:
*
* LX_MUTEX_INIT(mutexname);
*/
#define LX_MUTEX(mutexname) lx_mutex_ ## mutexname
#define LX_MUTEX_INIT(mutexname) lx_mutex_init_ ## mutexname()
#define LX_MUTEX_INIT_DECLARE(mutexname) extern void LX_MUTEX_INIT(mutexname)
void mutex_init(struct mutex *m);
void mutex_destroy(struct mutex *m);

View File

@ -877,6 +877,12 @@ void debug_check_no_locks_freed(const void *from, unsigned long len);
#include <lx_emul/mutex.h>
LX_MUTEX_INIT_DECLARE(dst_gc_mutex);
LX_MUTEX_INIT_DECLARE(proto_list_mutex);
#define dst_gc_mutex LX_MUTEX(dst_gc_mutex)
#define proto_list_mutex LX_MUTEX(proto_list_mutex)
/***********************************
** linux/rwlock_types.h/rwlock.h **

View File

@ -37,13 +37,26 @@
#include <lx_kit/backend_alloc.h>
struct Memory_object_base;
static Lx_kit::Env *lx_env;
static Genode::Object_pool<Memory_object_base> *memory_pool_ptr;
void Lx::lxcc_emul_init(Lx_kit::Env &env)
{
static Genode::Object_pool<Memory_object_base> memory_pool;
memory_pool_ptr = &memory_pool;
lx_env = &env;
LX_MUTEX_INIT(dst_gc_mutex);
LX_MUTEX_INIT(proto_list_mutex);
}
struct Memory_object_base : Genode::Object_pool<Memory_object_base>::Entry
{
Memory_object_base(Genode::Ram_dataspace_capability cap)
@ -59,9 +72,6 @@ struct Memory_object_base : Genode::Object_pool<Memory_object_base>::Entry
};
static Genode::Object_pool<Memory_object_base> memory_pool;
Genode::Ram_dataspace_capability
Lx::backend_alloc(Genode::addr_t size, Genode::Cache_attribute cached)
{
@ -70,7 +80,7 @@ Lx::backend_alloc(Genode::addr_t size, Genode::Cache_attribute cached)
Genode::Ram_dataspace_capability cap = lx_env->ram().alloc(size);
Memory_object_base *o = new (lx_env->heap()) Memory_object_base(cap);
memory_pool.insert(o);
memory_pool_ptr->insert(o);
return cap;
}
@ -80,11 +90,11 @@ void Lx::backend_free(Genode::Ram_dataspace_capability cap)
using namespace Genode;
Memory_object_base *object;
memory_pool.apply(cap, [&] (Memory_object_base *o) {
memory_pool_ptr->apply(cap, [&] (Memory_object_base *o) {
if (!o) return;
o->free();
memory_pool.remove(o);
memory_pool_ptr->remove(o);
object = o; /* save for destroy */
});
@ -359,7 +369,11 @@ class Avl_page : public Genode::Avl_node<Avl_page>
};
static Genode::Avl_tree<Avl_page> tree;
static Genode::Avl_tree<Avl_page> & tree()
{
static Genode::Avl_tree<Avl_page> _tree;
return _tree;
}
struct page *alloc_pages(gfp_t gfp_mask, unsigned int order)
@ -367,7 +381,7 @@ struct page *alloc_pages(gfp_t gfp_mask, unsigned int order)
Avl_page *p;
try {
p = (Avl_page *)new (lx_env->heap()) Avl_page(PAGE_SIZE << order);
tree.insert(p);
tree().insert(p);
} catch (...) { return 0; }
return p->page();
@ -386,9 +400,9 @@ void *__alloc_page_frag(struct page_frag_cache *nc,
void __free_page_frag(void *addr)
{
Avl_page *p = tree.first()->find_by_address((Genode::addr_t)addr);
Avl_page *p = tree().first()->find_by_address((Genode::addr_t)addr);
tree.remove(p);
tree().remove(p);
destroy(lx_env->heap(), p);
}
@ -399,7 +413,7 @@ void __free_page_frag(void *addr)
struct page *virt_to_head_page(const void *x)
{
Avl_page *p = tree.first()->find_by_address((Genode::addr_t)x);
Avl_page *p = tree().first()->find_by_address((Genode::addr_t)x);
lx_log(DEBUG_SLAB, "virt_to_head_page: %p page %p\n", x,p ? p->page() : 0);
return p ? p->page() : 0;
@ -412,9 +426,9 @@ void put_page(struct page *page)
return;
lx_log(DEBUG_SLAB, "put_page: %p", page);
Avl_page *p = tree.first()->find_by_address((Genode::addr_t)page->addr);
Avl_page *p = tree().first()->find_by_address((Genode::addr_t)page->addr);
tree.remove(p);
tree().remove(p);
destroy(lx_env->heap(), p);
}

View File

@ -65,7 +65,11 @@ struct Xoroshiro
};
static Xoroshiro xoroshiro(42);
static Xoroshiro & xoroshiro()
{
static Xoroshiro xoroshiro(42);
return xoroshiro;
}
/********************
@ -82,7 +86,7 @@ extern "C" void get_random_bytes(void *buf, int nbytes)
int const rounds = nbytes / 8;
for (int i = 0; i < rounds; i++) {
uint64_t const v = xoroshiro.get();
uint64_t const v = xoroshiro().get();
Genode::memcpy(p, &v, 8);
p += 8;
@ -93,12 +97,12 @@ extern "C" void get_random_bytes(void *buf, int nbytes)
return;
}
uint64_t const v = xoroshiro.get();
uint64_t const v = xoroshiro().get();
Genode::memcpy(p, &v, remain);
}
extern "C" unsigned int prandom_u32(void)
{
return xoroshiro.get();
return xoroshiro().get();
}

View File

@ -381,31 +381,31 @@ struct Vfs::Lxip_vfs_dir_handle final : Vfs::Lxip_vfs_handle
/**
* Queues of open handles to poll
*/
static Vfs::Lxip_vfs_file_handle::Fifo _io_progress_waiters;
static Vfs::Lxip_vfs_file_handle::Fifo _read_ready_waiters;
static Vfs::Lxip_vfs_file_handle::Fifo *_io_progress_waiters_ptr;
static Vfs::Lxip_vfs_file_handle::Fifo *_read_ready_waiters_ptr;
static void poll_all()
{
_io_progress_waiters.for_each(
_io_progress_waiters_ptr->for_each(
[&] (Vfs::Lxip_vfs_file_handle::Fifo_element &elem) {
Vfs::Lxip_vfs_file_handle &handle = elem.object();
if (handle.file) {
if (handle.file->poll()) {
/* do not notify again until some I/O queues */
_io_progress_waiters.remove(elem);
_io_progress_waiters_ptr->remove(elem);
handle.io_progress_response();
}
}
});
_read_ready_waiters.for_each(
_read_ready_waiters_ptr->for_each(
[&] (Vfs::Lxip_vfs_file_handle::Fifo_element &elem) {
Vfs::Lxip_vfs_file_handle &handle = elem.object();
if (handle.file) {
if (handle.file->poll()) {
/* do not notify again until notify_read_ready */
_read_ready_waiters.remove(elem);
_read_ready_waiters_ptr->remove(elem);
handle.read_ready_response();
}
@ -513,7 +513,7 @@ class Vfs::Lxip_data_file final : public Vfs::Lxip_file
Lxip::ssize_t ret = _sock.ops->recvmsg(&_sock, &msg, len, MSG_DONTWAIT);
if (ret == -EAGAIN) {
handle.io_enqueue(_io_progress_waiters);
handle.io_enqueue(*_io_progress_waiters_ptr);
throw Would_block();
}
return ret;
@ -843,10 +843,10 @@ class Vfs::Lxip_remote_file final : public Vfs::Lxip_file
int const res = _sock.ops->recvmsg(&_sock, &msg, 0, MSG_DONTWAIT|MSG_PEEK);
if (res == -EAGAIN) {
handle.io_enqueue(_io_progress_waiters);
handle.io_enqueue(*_io_progress_waiters_ptr);
throw Would_block();
}
if (res < 0) return -1;
if (res < 0) return -1;
}
break;
case Lxip::Protocol_dir::TYPE_STREAM:
@ -924,7 +924,7 @@ class Vfs::Lxip_accept_file final : public Vfs::Lxip_file
return Genode::strlen(dst);
}
handle.io_enqueue(_io_progress_waiters);
handle.io_enqueue(*_io_progress_waiters_ptr);
throw Would_block();
}
};
@ -1855,8 +1855,8 @@ class Vfs::Lxip_file_system : public Vfs::File_system,
dynamic_cast<Vfs::Lxip_vfs_file_handle*>(handle);
if (file_handle) {
_io_progress_waiters.remove(file_handle->io_progress_elem);
_read_ready_waiters.remove(file_handle->read_ready_elem);
_io_progress_waiters_ptr->remove(file_handle->io_progress_elem);
_read_ready_waiters_ptr->remove(file_handle->read_ready_elem);
}
Genode::destroy(handle->alloc(), handle);
@ -1913,7 +1913,7 @@ class Vfs::Lxip_file_system : public Vfs::File_system,
if (handle) {
if (!handle->read_ready_elem.enqueued())
_read_ready_waiters.enqueue(handle->read_ready_elem);
_read_ready_waiters_ptr->enqueue(handle->read_ready_elem);
return true;
}
@ -1971,6 +1971,12 @@ struct Lxip_factory : Vfs::File_system_factory
extern "C" Vfs::File_system_factory *vfs_file_system_factory(void)
{
static Vfs::Lxip_vfs_file_handle::Fifo io_progress_waiters;
static Vfs::Lxip_vfs_file_handle::Fifo read_ready_waiters;
_io_progress_waiters_ptr = &io_progress_waiters;
_read_ready_waiters_ptr = &read_ready_waiters;
static Lxip_factory factory;
return &factory;
}

View File

@ -484,6 +484,24 @@ int alloc_bucket_spinlocks(spinlock_t **locks, unsigned int *locks_mask,
#include <lx_emul/mutex.h>
LX_MUTEX_INIT_DECLARE(crypto_default_rng_lock);
LX_MUTEX_INIT_DECLARE(fanout_mutex);
LX_MUTEX_INIT_DECLARE(genl_mutex);
LX_MUTEX_INIT_DECLARE(proto_list_mutex);
LX_MUTEX_INIT_DECLARE(rate_ctrl_mutex);
LX_MUTEX_INIT_DECLARE(reg_regdb_apply_mutex);
LX_MUTEX_INIT_DECLARE(rfkill_global_mutex);
LX_MUTEX_INIT_DECLARE(rtnl_mutex);
#define crypto_default_rng_lock LX_MUTEX(crypto_default_rng_lock)
#define fanout_mutex LX_MUTEX(fanout_mutex)
#define genl_mutex LX_MUTEX(genl_mutex)
#define proto_list_mutex LX_MUTEX(proto_list_mutex)
#define rate_ctrl_mutex LX_MUTEX(rate_ctrl_mutex)
#define reg_regdb_apply_mutex LX_MUTEX(reg_regdb_apply_mutex)
#define rfkill_global_mutex LX_MUTEX(rfkill_global_mutex)
#define rtnl_mutex LX_MUTEX(rtnl_mutex)
/*******************
** linux/rwsem.h **

View File

@ -185,6 +185,15 @@ void wifi_init(Genode::Env &env, Genode::Lock &lock, bool disable_11n,
{
Lx_kit::construct_env(env);
LX_MUTEX_INIT(crypto_default_rng_lock);
LX_MUTEX_INIT(fanout_mutex);
LX_MUTEX_INIT(genl_mutex);
LX_MUTEX_INIT(proto_list_mutex);
LX_MUTEX_INIT(rate_ctrl_mutex);
LX_MUTEX_INIT(reg_regdb_apply_mutex);
LX_MUTEX_INIT(rfkill_global_mutex);
LX_MUTEX_INIT(rtnl_mutex);
_wpa_lock = &lock;
INIT_LIST_HEAD(&init_net.dev_base_head);

View File

@ -13,20 +13,18 @@
#include <lx_kit/env.h>
/*
* Lx_kit enviroment instance
*/
static Genode::Constructible<Lx_kit::Env> _env;
static Lx_kit::Env *_env_ptr;
Lx_kit::Env &Lx_kit::env()
{
return *_env;
return *_env_ptr;
}
Lx_kit::Env &Lx_kit::construct_env(Genode::Env &env)
{
_env.construct(env);
return *_env;
static Lx_kit::Env _env(env);
_env_ptr = &_env;
return _env;
}

View File

@ -335,19 +335,26 @@ class Lx_kit::Malloc : public Lx::Malloc
** Lx::Malloc implementation **
*******************************/
static Genode::Constructible<Lx_kit::Slab_backend_alloc> _mem_backend_alloc;
static Genode::Constructible<Lx_kit::Slab_backend_alloc> _dma_backend_alloc;
static Genode::Constructible<Lx_kit::Malloc> _mem_alloc;
static Genode::Constructible<Lx_kit::Malloc> _dma_alloc;
static Lx_kit::Slab_backend_alloc *_mem_backend_alloc_ptr;
static Lx_kit::Slab_backend_alloc *_dma_backend_alloc_ptr;
static Lx_kit::Malloc *_mem_alloc_ptr;
static Lx_kit::Malloc *_dma_alloc_ptr;
void Lx::malloc_init(Genode::Env &env, Genode::Allocator &md_alloc)
{
_mem_backend_alloc.construct(env, md_alloc, Genode::CACHED);
_dma_backend_alloc.construct(env, md_alloc, Genode::UNCACHED);
static Lx_kit::Slab_backend_alloc mem_backend_alloc(env, md_alloc, Genode::CACHED);
static Lx_kit::Slab_backend_alloc dma_backend_alloc(env, md_alloc, Genode::UNCACHED);
_mem_alloc.construct(*_mem_backend_alloc, Genode::CACHED);
_dma_alloc.construct(*_dma_backend_alloc, Genode::UNCACHED);
_mem_backend_alloc_ptr = &mem_backend_alloc;
_dma_backend_alloc_ptr = &dma_backend_alloc;
static Lx_kit::Malloc mem_alloc(mem_backend_alloc, Genode::CACHED);
static Lx_kit::Malloc dma_alloc(dma_backend_alloc, Genode::UNCACHED);
_mem_alloc_ptr = &mem_alloc;
_dma_alloc_ptr = &dma_alloc;
}
@ -355,22 +362,22 @@ void Lx::malloc_init(Genode::Env &env, Genode::Allocator &md_alloc)
* Cached memory backend allocator
*/
Lx::Slab_backend_alloc &Lx::Slab_backend_alloc::mem() {
return *_mem_backend_alloc; }
return *_mem_backend_alloc_ptr; }
/**
* DMA memory backend allocator
*/
Lx::Slab_backend_alloc &Lx::Slab_backend_alloc::dma() {
return *_dma_backend_alloc; }
return *_dma_backend_alloc_ptr; }
/**
* Cached memory allocator
*/
Lx::Malloc &Lx::Malloc::mem() { return *_mem_alloc; }
Lx::Malloc &Lx::Malloc::mem() { return *_mem_alloc_ptr; }
/**
* DMA memory allocator
*/
Lx::Malloc &Lx::Malloc::dma() { return *_dma_alloc; }
Lx::Malloc &Lx::Malloc::dma() { return *_dma_alloc_ptr; }