diff --git a/repos/dde_linux/lib/mk/lxip.mk b/repos/dde_linux/lib/mk/lxip.mk index 0d39e386b..c3181e965 100644 --- a/repos/dde_linux/lib/mk/lxip.mk +++ b/repos/dde_linux/lib/mk/lxip.mk @@ -3,8 +3,7 @@ SHARED_LIB = yes LIB_DIR = $(REP_DIR)/src/lib/lxip LIB_INC_DIR = $(LIB_DIR)/include -# FIXME should we *really* effecticely add dde_kit to this shared library? -LIBS += dde_kit +LIBS += lx LX_CONTRIB_DIR := $(call select_from_ports,dde_linux)/src/lib/lxip NET_DIR := $(LX_CONTRIB_DIR)/net diff --git a/repos/dde_linux/src/lib/lxip/dummies.cc b/repos/dde_linux/src/lib/lxip/dummies.cc index cae00c21e..036ae83bf 100644 --- a/repos/dde_linux/src/lib/lxip/dummies.cc +++ b/repos/dde_linux/src/lib/lxip/dummies.cc @@ -323,7 +323,6 @@ DUMMY(-1, mod_delayed_work) DUMMY(-1, module_put) DUMMY(-1, move_addr_to_kernel) DUMMY(-1, mq_qdisc_ops) -DUMMY(-1, msecs_to_jiffies) DUMMY(-1, msleep) DUMMY(-1, mutex_is_locked) DUMMY(-1, need_resched) diff --git a/repos/dde_linux/src/lib/lxip/include/lx_emul.h b/repos/dde_linux/src/lib/lxip/include/lx_emul.h index bfd1575f7..af6c201f3 100644 --- a/repos/dde_linux/src/lib/lxip/include/lx_emul.h +++ b/repos/dde_linux/src/lib/lxip/include/lx_emul.h @@ -17,14 +17,7 @@ #ifndef _LX_EMUL_H_ #define _LX_EMUL_H_ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -#include -#include -#include +#include #define DEBUG_PRINTK 1 #define DEBUG_SLAB 0 @@ -39,31 +32,6 @@ extern "C" { #define KBUILD_MODNAME "mod-noname" -/*************** - ** asm/bug.h ** - ***************/ - -#define WARN_ON(condition) ({ \ - int ret = !!(condition); \ - if (ret) dde_kit_printf("[%s] WARN_ON(" #condition ")\n", __func__); \ - ret; }) - -#define WARN(condition, format, ...) ({ \ - int ret = !!(condition); \ - if (ret) dde_kit_printf("[%s] WARN(" #condition ") " format "\n" , __func__, __VA_ARGS__); \ - ret; }) - -#define WARN_ON_ONCE WARN_ON -#define WARN_ONCE WARN - -#define BUG() do { \ - dde_kit_debug("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \ - while (1); \ -} while (0) - -#define BUG_ON(condition) do { if (condition) BUG(); } while(0) - - /******************************* ** linux/errno.h and friends ** *******************************/ @@ -239,31 +207,10 @@ int try_module_get(struct module *); #define CONFIG_DEFAULT_TCP_CONG "cubic" -/*************** - ** asm/bug.h ** - ***************/ - -#define BUG() do { \ - dde_kit_debug("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \ - while (1); \ -} while (0) - - /******************* ** linux/types.h ** *******************/ -typedef dde_kit_int8_t int8_t; -typedef dde_kit_int16_t int16_t; -typedef dde_kit_int32_t int32_t; -typedef dde_kit_int64_t int64_t; - -typedef dde_kit_uint8_t uint8_t; -typedef dde_kit_uint16_t uint16_t; -typedef dde_kit_uint32_t uint32_t; -typedef dde_kit_uint64_t uint64_t; -typedef dde_kit_size_t size_t; - typedef uint32_t uint; typedef int8_t s8; @@ -353,10 +300,7 @@ enum { true = 1, false = 0 }; ** linux/jiffies.h ** *********************/ -/* we directly map 'jiffies' to 'dde_kit_timer_ticks' */ -#define jiffies dde_kit_timer_ticks - -extern volatile unsigned long jiffies; +extern unsigned long jiffies; enum { INITIAL_JIFFIES = 0 }; @@ -371,6 +315,7 @@ static inline long time_before(long a, long b) { return time_after(b, a); } static inline long time_before_eq(long a, long b) { return time_after_eq(b ,a); } clock_t jiffies_to_clock_t(unsigned long); +void update_jiffies(void); /****************** @@ -441,11 +386,11 @@ void sg_set_page(struct scatterlist *, struct page *, unsigned int, #define KERN_WARNING KERN_WARN -#define pr_crit(fmt, ...) dde_kit_printf(KERN_CRIT fmt, ##__VA_ARGS__) -#define pr_emerg(fmt, ...) dde_kit_printf(KERN_EMERG fmt, ##__VA_ARGS__) -#define pr_err(fmt, ...) dde_kit_printf(KERN_ERR fmt, ##__VA_ARGS__) -#define pr_warn(fmt, ...) dde_kit_printf(KERN_WARN fmt, ##__VA_ARGS__) -#define pr_info(fmt, ...) dde_kit_printf(KERN_INFO fmt, ##__VA_ARGS__) +#define pr_crit(fmt, ...) lx_printf(KERN_CRIT fmt, ##__VA_ARGS__) +#define pr_emerg(fmt, ...) lx_printf(KERN_EMERG fmt, ##__VA_ARGS__) +#define pr_err(fmt, ...) lx_printf(KERN_ERR fmt, ##__VA_ARGS__) +#define pr_warn(fmt, ...) lx_printf(KERN_WARN fmt, ##__VA_ARGS__) +#define pr_info(fmt, ...) lx_printf(KERN_INFO fmt, ##__VA_ARGS__) #define pr_notice(fmt, ...) printk(KERN_NOTICE fmt, ##__VA_ARGS__) #define pr_cont(fmt, ...) printk(KERN_CONT fmt, ##__VA_ARGS__) @@ -468,15 +413,14 @@ static inline int _printk(const char *fmt, ...) { va_list args; va_start(args, fmt); - dde_kit_vprintf(fmt, args); + lx_vprintf(fmt, args); va_end(args); return 0; } #if DEBUG_PRINTK #define printk _printk -#define vprintk dde_kit_vprintf -#define panic dde_kit_panic +#define vprintk lx_vprintf #else static inline int printk(const char *fmt, ...) @@ -485,7 +429,6 @@ static inline int printk(const char *fmt, ...) } #define vprintk(...) -#define panic(...) #endif @@ -974,9 +917,6 @@ enum { PAGE_SHIFT = 12, }; -#ifdef __cplusplus -#define private priv -#endif struct page { int pfmemalloc; @@ -984,9 +924,6 @@ struct page atomic_t _count; void *addr; unsigned long private; -#ifdef __cplusplus -#undef priv -#endif } __attribute((packed)); @@ -2241,17 +2178,12 @@ ssize_t splice_to_pipe(struct pipe_inode_info *, struct splice_pipe_desc *); /***************** ** linux/aio.h ** *****************/ -#ifdef __cplusplus -#define private priv -#endif + struct kiocb { void *private; }; -#ifdef __cplusplus -#undef private -#endif /***************** ** linux/uio.h ** @@ -2499,9 +2431,7 @@ struct u64_stats_sync { }; ** net/net_namespace.h ** *************************/ -#define new _new #include -#undef new #include #include #include @@ -2795,13 +2725,7 @@ void csum_replace2(__sum16 *, __be16, __be16); ** uapi/linux/net_tstamp.h ** *****************************/ -#ifdef __cplusplus -#define class device_class -#endif #include -#ifdef __cplusplus -#undef class -#endif #include enum { @@ -3327,9 +3251,5 @@ void log_sock(struct socket *sock); void lx_trace_event(char const *, ...) __attribute__((format(printf, 1, 2))); -#ifdef __cplusplus -} -#endif /* __cplusplus */ - #endif /* _LX_EMUL_H_ */ diff --git a/repos/dde_linux/src/lib/lxip/init.c b/repos/dde_linux/src/lib/lxip/init.c index c53df4125..26f0a652d 100644 --- a/repos/dde_linux/src/lib/lxip/init.c +++ b/repos/dde_linux/src/lib/lxip/init.c @@ -10,7 +10,6 @@ * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. */ -#include #include #include #include @@ -58,9 +57,6 @@ int lxip_init(char *address_config) /* init data */ INIT_LIST_HEAD(&init_net.dev_base_head); - /*start jiffies */ - dde_kit_timer_init(0, 0); - /* call __setup stuff */ __ip_auto_config_setup(address_config); diff --git a/repos/dde_linux/src/lib/lxip/lxc_emul.c b/repos/dde_linux/src/lib/lxip/lxc_emul.c index d4a8beb9a..11389af41 100644 --- a/repos/dde_linux/src/lib/lxip/lxc_emul.c +++ b/repos/dde_linux/src/lib/lxip/lxc_emul.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -33,7 +32,7 @@ struct kmem_cache struct kmem_cache *kmem_cache_create(const char *name, size_t size, size_t align, unsigned long falgs, void (*ctor)(void *)) { - dde_kit_log(DEBUG_SLAB, "\"%s\" obj_size=%zd", name, size); + lx_log(DEBUG_SLAB, "\"%s\" obj_size=%zd", name, size); struct kmem_cache *cache; @@ -57,49 +56,25 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, size_t align void *kmem_cache_alloc_node(struct kmem_cache *cache, gfp_t flags, int node) { - dde_kit_log(DEBUG_SLAB, "\"%s\" alloc obj_size=%u", cache->name,cache->size); + lx_log(DEBUG_SLAB, "\"%s\" alloc obj_size=%u", cache->name,cache->size); return kmalloc(cache->size, 0); } void *kmem_cache_alloc(struct kmem_cache *cache, gfp_t flags) { - dde_kit_log(DEBUG_SLAB, "\"%s\" alloc obj_size=%u", cache->name,cache->size); + lx_log(DEBUG_SLAB, "\"%s\" alloc obj_size=%u", cache->name,cache->size); return kmalloc(cache->size, 0); } void kmem_cache_free(struct kmem_cache *cache, void *objp) { - dde_kit_log(DEBUG_SLAB, "\"%s\" (%p)", cache->name, objp); + lx_log(DEBUG_SLAB, "\"%s\" (%p)", cache->name, objp); kfree(objp); } -void *alloc_large_system_hash(const char *tablename, - unsigned long bucketsize, - unsigned long numentries, - int scale, - int flags, - unsigned int *_hash_shift, - unsigned int *_hash_mask, - unsigned long low_limit, - unsigned long high_limit) -{ - unsigned long elements = numentries ? numentries : high_limit; - unsigned long nlog2 = ilog2(elements); - nlog2 <<= (1 << nlog2) < elements ? 1 : 0; - - void *table = dde_kit_simple_malloc(elements * bucketsize); - - if (_hash_mask) - *_hash_mask = (1 << nlog2) - 1; - if (_hash_shift) - *_hash_shift = nlog2; - - return table; -} - /******************** ** linux/bitmap.h ** ********************/ diff --git a/repos/dde_linux/src/lib/lxip/lxcc_emul.cc b/repos/dde_linux/src/lib/lxip/lxcc_emul.cc index b79a783e8..0d8ab3956 100644 --- a/repos/dde_linux/src/lib/lxip/lxcc_emul.cc +++ b/repos/dde_linux/src/lib/lxip/lxcc_emul.cc @@ -17,12 +17,12 @@ #include #include +#include #include +#include + #include -extern "C" { -#include -} /* * VM-area to reserve for back-end allocator @@ -379,6 +379,7 @@ void *kzalloc_node(size_t size, gfp_t flags, int node) return kzalloc(size, 0); } + size_t ksize(const void *p) { if (!(Malloc::mem()->inside((Genode::addr_t)p))) { @@ -391,6 +392,32 @@ size_t ksize(const void *p) } +void *alloc_large_system_hash(const char *tablename, + unsigned long bucketsize, + unsigned long numentries, + int scale, + int flags, + unsigned int *_hash_shift, + unsigned int *_hash_mask, + unsigned long low_limit, + unsigned long high_limit) +{ + unsigned long elements = numentries ? numentries : high_limit; + unsigned long nlog2 = ilog2(elements); + nlog2 <<= (1 << nlog2) < elements ? 1 : 0; + + void *table = Genode::env()->heap()->alloc(elements * bucketsize); + + if (_hash_mask) + *_hash_mask = (1 << nlog2) - 1; + if (_hash_shift) + *_hash_shift = nlog2; + + return table; +} + + + /******************** ** linux/string.h ** ********************/ @@ -515,7 +542,8 @@ static void __wait_event(signed long timeout) while (timeout > jiffies && !Net::Env::receiver()->pending()) { timer.msleep(1); - //dde_kit_thread_msleep(1); + update_jiffies(); + if (timeout <= jiffies) return; } @@ -584,7 +612,7 @@ class Avl_page : public Genode::Avl_node _page->addr = (void *)_addr; atomic_set(&_page->_count, 1); - dde_kit_log(DEBUG_SLAB, "alloc page: %p addr: %lx-%lx", _page, _addr, _addr + size); + lx_log(DEBUG_SLAB, "alloc page: %p addr: %lx-%lx", _page, _addr, _addr + size); } virtual ~Avl_page() @@ -632,7 +660,7 @@ struct page *alloc_pages(gfp_t gfp_mask, unsigned int order) struct page *virt_to_head_page(const void *x) { Avl_page *p = tree.first()->find_by_address((Genode::addr_t)x); - dde_kit_log(DEBUG_SLAB, "virt_to_head_page: %p page %p\n", x,p ? p->page() : 0); + lx_log(DEBUG_SLAB, "virt_to_head_page: %p page %p\n", x,p ? p->page() : 0); return p ? p->page() : 0; } @@ -643,7 +671,7 @@ void put_page(struct page *page) if (!atomic_dec_and_test(&page->_count)) return; - dde_kit_log(DEBUG_SLAB, "put_page: %p", page); + lx_log(DEBUG_SLAB, "put_page: %p", page); Avl_page *p = tree.first()->find_by_address((Genode::addr_t)page->addr); tree.remove(p); diff --git a/repos/dde_linux/src/lib/lxip/socket_handler.cc b/repos/dde_linux/src/lib/lxip/socket_handler.cc index ae224ccb4..10df75e4d 100644 --- a/repos/dde_linux/src/lib/lxip/socket_handler.cc +++ b/repos/dde_linux/src/lib/lxip/socket_handler.cc @@ -26,18 +26,17 @@ static const bool verbose = false; namespace Linux { - extern "C" { + #include #include #include #include - extern int sock_setsockopt(struct socket *sock, int level, int op, char __user *optval, unsigned int optlen); extern int sock_getsockopt(struct socket *sock, int level, int op, char __user *optval, int __user *optlen); - } + #include } namespace Net diff --git a/repos/dde_linux/src/lib/lxip/timer_handler.cc b/repos/dde_linux/src/lib/lxip/timer_handler.cc index 8fc3888a5..389c8a87a 100644 --- a/repos/dde_linux/src/lib/lxip/timer_handler.cc +++ b/repos/dde_linux/src/lib/lxip/timer_handler.cc @@ -13,85 +13,289 @@ #include #include +#include +#include +#include +#include +#include #include +#include + #include -extern "C" { -#include -} +#include -static void handler(void *timer); + +/********************* + ** linux/jiffies.h ** + *********************/ + +unsigned long jiffies; + +unsigned long msecs_to_jiffies(const unsigned int m) { return m / (1000 / HZ); } /** - * Signal context for time-outs + * Lx::Timer */ -class Timer_context +namespace Lx { + class Timer; +} + +class Lx::Timer { + public: + + /** + * Context encapsulates a regular linux timer_list + */ + struct Context : public Lx::List::Element + { + enum { INVALID_TIMEOUT = ~0UL }; + enum Type { LIST }; + + Type type; + void *timer; + bool pending { false }; + unsigned long timeout { INVALID_TIMEOUT }; /* absolute in jiffies */ + bool programmed { false }; + + Context(struct timer_list *timer) : type(LIST), timer(timer) { } + + void expires(unsigned long e) + { + if (type == LIST) + static_cast(timer)->expires = e; + } + + void function() + { + switch (type) { + case LIST: + { + timer_list *t = static_cast(timer); + if (t->function) + t->function(t->data); + } + break; + + } + } + }; + private: - timer_list *_timer; /* Linux timer */ - dde_kit_timer *_dde_timer; /* DDE kit timer */ - Genode::Signal_dispatcher _dispatcher; - - /* call timer function */ - void _handle(unsigned) { _timer->function(_timer->data); } + ::Timer::Connection _timer_conn; + Lx::List _list; + Genode::Signal_dispatcher _dispatcher; + Genode::Tslab _timer_alloc; public: - Timer_context(timer_list *timer) - : _timer(timer), _dde_timer(0), - _dispatcher(*Net::Env::receiver(), *this, &Timer_context::_handle) {} + bool ready { true }; - /* schedule next timeout */ - void schedule(unsigned long expires) + private: + + /** + * Lookup local timer + */ + Context *_find_context(void const *timer) { - if (!_dde_timer) - _dde_timer = dde_kit_timer_add(handler, this, expires); - else - dde_kit_timer_schedule_absolute(_dde_timer, expires); + for (Context *c = _list.first(); c; c = c->next()) + if (c->timer == timer) + return c; + + return 0; } /** - * Return true if timer is pending + * Program the first timer in the list + * + * The first timer is programmed if the 'programmed' flag was not set + * before. The second timer is flagged as not programmed as + * 'Timer::trigger_once' invalidates former registered one-shot + * timeouts. */ - bool pending() const + void _program_first_timer() { - return _dde_timer ? dde_kit_timer_pending(_dde_timer) : false; + Context *ctx = _list.first(); + if (!ctx) + return; + + if (ctx->programmed) + return; + + /* calculate relative microseconds for trigger */ + unsigned long us = ctx->timeout > jiffies ? + jiffies_to_msecs(ctx->timeout - jiffies) * 1000 : 0; + _timer_conn.trigger_once(us); + + ctx->programmed = true; + + /* possibly programmed successor must be reprogrammed later */ + if (Context *next = ctx->next()) + next->programmed = false; } /** - * Return internal signal cap + * Schedule timer + * + * Add the context to the scheduling list depending on its timeout + * and reprogram the first timer. */ - Genode::Signal_context_capability cap() const { return _dispatcher; } - void submit() { _dispatcher.submit(1); } + void _schedule_timer(Context *ctx, unsigned long expires) + { + _list.remove(ctx); + + ctx->timeout = expires; + ctx->pending = true; + ctx->programmed = false; + /* + * Also write the timeout value to the expires field in + * struct timer_list because the checks + * it directly. + */ + ctx->expires(expires); + + Context *c; + for (c = _list.first(); c; c = c->next()) + if (ctx->timeout <= c->timeout) + break; + _list.insert_before(ctx, c); + + _program_first_timer(); + } /** - * Convert 'timer_list' to 'Timer_conext' + * Handle trigger_once signal */ - static Timer_context *to_ctx(timer_list const *timer) { - return static_cast(timer->timer); } - - void remove() + void _handle(unsigned) { - if (_dde_timer) - dde_kit_timer_del(_dde_timer); + update_jiffies(); - _dde_timer = 0; + while (Lx::Timer::Context *ctx = _list.first()) { + if (ctx->timeout > jiffies) + break; + + ctx->function(); + del(ctx->timer); + } } + + public: + + /** + * Constructor + */ + Timer() + : + _dispatcher(*Net::Env::receiver(), *this, &Lx::Timer::_handle), + _timer_alloc(Genode::env()->heap()) + { + _timer_conn.sigh(_dispatcher); + jiffies = 0; + } + + /** + * Add new linux timer + */ + template + void add(TIMER *timer) + { + Context *t = new (&_timer_alloc) Context(timer); + _list.append(t); + } + + /** + * Delete linux timer + */ + int del(void *timer) + { + Context *ctx = _find_context(timer); + + /** + * If the timer expired it was already cleaned up after its + * execution. + */ + if (!ctx) + return 0; + + int rv = ctx->timeout != Context::INVALID_TIMEOUT ? 1 : 0; + + _list.remove(ctx); + destroy(&_timer_alloc, ctx); + + return rv; + } + + /** + * Initial scheduling of linux timer + */ + int schedule(void *timer, unsigned long expires) + { + Context *ctx = _find_context(timer); + if (!ctx) { + PERR("schedule unknown timer %p", timer); + return -1; /* XXX better use 0 as rv? */ + } + + /* + * If timer was already active return 1, otherwise 0. The return + * value is needed by mod_timer(). + */ + int rv = ctx->timeout != Context::INVALID_TIMEOUT ? 1 : 0; + + _schedule_timer(ctx, expires); + + return rv; + } + + /** + * Schedule next linux timer + */ + void schedule_next() { _program_first_timer(); } + + /** + * Check if the timer is currently pending + */ + bool pending(void const *timer) + { + Context *ctx = _find_context(timer); + if (!ctx) { + return false; + } + + return ctx->pending; + } + + Context *find(struct timer_list const *timer) { + return _find_context(timer); } + + /** + * Update jiffie counter + */ + void update_jiffies() + { + jiffies = msecs_to_jiffies(_timer_conn.elapsed_ms()); + } + + /** + * Get first timer context + */ + Context* first() { return _list.first(); } + + static Timer &t() + { + static Lx::Timer _t; + return _t; + } + }; -/** - * C handler for DDE timer interface - */ -static void handler(void *timer) +void update_jiffies() { - Timer_context *t = static_cast(timer); - t->submit(); - /* set context and submit - Genode::Signal_transmitter transmitter(t->cap()); - transmitter.submit(); */ + Lx::Timer::t().update_jiffies(); } @@ -99,9 +303,7 @@ static void handler(void *timer) ** linux/timer.h ** *******************/ -void init_timer(struct timer_list *timer) { - timer->timer = (void *) new (Genode::env()->heap()) Timer_context(timer); } - +void init_timer(struct timer_list *timer) { } void add_timer(struct timer_list *timer) { @@ -110,12 +312,15 @@ void add_timer(struct timer_list *timer) } + int mod_timer(struct timer_list *timer, unsigned long expires) { - dde_kit_log(DEBUG_TIMER, "Timer: %p j: %lu ex: %lu func %p", - timer, jiffies, expires, timer->function); - Timer_context::to_ctx(timer)->schedule(expires); - return 0; + update_jiffies(); + + if (!Lx::Timer::t().find(timer)) + Lx::Timer::t().add(timer); + + return Lx::Timer::t().schedule(timer, expires); } @@ -124,22 +329,25 @@ void setup_timer(struct timer_list *timer,void (*function)(unsigned long), { timer->function = function; timer->data = data; - init_timer(timer); } int timer_pending(const struct timer_list * timer) { - bool pending = Timer_context::to_ctx(timer)->pending(); - dde_kit_log(DEBUG_TIMER, "Pending %p %u", timer, pending); + bool pending = Lx::Timer::t().pending(timer); + lx_log(DEBUG_TIMER, "Pending %p %u", timer, pending); return pending; } int del_timer(struct timer_list *timer) { - dde_kit_log(DEBUG_TIMER, "Delete timer %p", timer); - Timer_context::to_ctx(timer)->remove(); - return 0; + update_jiffies(); + lx_log(DEBUG_TIMER, "Delete timer %p", timer); + int rv = Lx::Timer::t().del(timer); + Lx::Timer::t().schedule_next(); + + return rv; } + diff --git a/repos/dde_linux/src/lib/usb/include/lx_emul.h b/repos/dde_linux/src/lib/usb/include/lx_emul.h index eefdd2f6a..32a9bd6a9 100644 --- a/repos/dde_linux/src/lib/usb/include/lx_emul.h +++ b/repos/dde_linux/src/lib/usb/include/lx_emul.h @@ -306,7 +306,6 @@ typedef unsigned short ushort; ** linux/jiffies.h ** *********************/ -/* we directly map 'jiffies' to 'dde_kit_timer_ticks' */ extern unsigned long jiffies; unsigned long msecs_to_jiffies(const unsigned int m); unsigned int jiffies_to_msecs(const unsigned long j);