Re: CURRENT broken on Raspberry Pi 2?

2019-03-11 Thread Ryo Shimizu


>>>> Might I suggest a reference count?  RUN_ONCE() can initialize the mutex 
>>>> around the counter, and then the counter can keep track of the init's and 
>>>> fini's called, and only do the work on t
>he 0->1 edge and the 1->0 edge
>>> .
>>>
>>> You also need to destroy the mutex somewhen.
>>>
>>> RUN_ONCE needs to learn a bit more about life cycles.
>>
>> I made INIT_ONCE(9) and FINI_ONCE(9) with reference counter.
>> Is this OK like this?
>
>Hi,
>
>Thanks for working on this.
>
>At the moment your _{init,fini}_once are missing cv_broadcasts, but I 
>wonder if we can merge _{run,init}_once and avoid duplicate code.
>
>I'm not sure if _fini_done should ever wait.

Added tech-kern.

I fixed. thanks.
we need kernel version bump due to changing once_t and deleting _run_once().


cvs -q diff -aup sys/once.h kern/subr_once.c
Index: sys/once.h
===
RCS file: /src/cvs/cvsroot-netbsd/src/sys/sys/once.h,v
retrieving revision 1.6
diff -a -u -p -r1.6 once.h
--- sys/once.h  3 Mar 2018 19:21:59 -   1.6
+++ sys/once.h  11 Mar 2019 10:25:18 -
@@ -31,23 +31,29 @@
 #define_SYS_ONCE_H_
 
 typedef struct {
-   unsigned o_status;
int o_error;
+   uint16_t o_refcnt;
+   uint16_t o_status;
 #defineONCE_VIRGIN 0
 #defineONCE_RUNNING1
 #defineONCE_DONE   2
 } once_t;
 
 void once_init(void);
-int _run_once(once_t *, int (*)(void));
+int _init_once(once_t *, int (*)(void));
+void _fini_once(once_t *, void (*)(void));
 
 #defineONCE_DECL(o) \
-   once_t (o) __read_mostly = { \
+   once_t (o) = { \
.o_status = 0, \
+   .o_refcnt = 0, \
};
 
 #defineRUN_ONCE(o, fn) \
 (__predict_true((o)->o_status == ONCE_DONE) ? \
-  ((o)->o_error) : _run_once((o), (fn)))
+  ((o)->o_error) : _init_once((o), (fn)))
+
+#defineINIT_ONCE(o, fn)_init_once((o), (fn))
+#defineFINI_ONCE(o, fn)_fini_once((o), (fn))
 
 #endif /* _SYS_ONCE_H_ */
Index: kern/subr_once.c
===
RCS file: /src/cvs/cvsroot-netbsd/src/sys/kern/subr_once.c,v
retrieving revision 1.6
diff -a -u -p -r1.6 subr_once.c
--- kern/subr_once.c15 Mar 2009 17:14:40 -  1.6
+++ kern/subr_once.c11 Mar 2019 10:33:37 -
@@ -48,13 +48,17 @@ once_init(void)
 }
 
 int
-_run_once(once_t *o, int (*fn)(void))
+_init_once(once_t *o, int (*fn)(void))
 {
-
/* Fastpath handled by RUN_ONCE() */
 
+   int error;
+
mutex_enter(&oncemtx);
-   if (o->o_status == ONCE_VIRGIN) {
+   while (o->o_status == ONCE_RUNNING)
+   cv_wait(&oncecv, &oncemtx);
+
+   if (o->o_refcnt++ == 0) {
o->o_status = ONCE_RUNNING;
mutex_exit(&oncemtx);
o->o_error = fn();
@@ -62,10 +66,34 @@ _run_once(once_t *o, int (*fn)(void))
o->o_status = ONCE_DONE;
cv_broadcast(&oncecv);
}
-   while (o->o_status != ONCE_DONE)
+   KASSERT(o->o_refcnt != 0);  /* detect overflow */
+
+   while (o->o_status == ONCE_RUNNING)
cv_wait(&oncecv, &oncemtx);
+   error = o->o_error;
mutex_exit(&oncemtx);
 
-   KASSERT(o->o_status == ONCE_DONE);
-   return o->o_error;
+   return error;
+}
+
+void
+_fini_once(once_t *o, void (*fn)(void))
+{
+   mutex_enter(&oncemtx);
+   while (o->o_status == ONCE_RUNNING)
+   cv_wait(&oncecv, &oncemtx);
+
+   KASSERT(o->o_refcnt != 0);  /* we need to call _init_once() once */
+   if (--o->o_refcnt == 0) {
+   o->o_status = ONCE_RUNNING;
+   mutex_exit(&oncemtx);
+   fn();
+       mutex_enter(&oncemtx);
+   o->o_status = ONCE_VIRGIN;
+   cv_broadcast(&oncecv);
+   }
+
+   while (o->o_status == ONCE_RUNNING)
+   cv_wait(&oncecv, &oncemtx);
+   mutex_exit(&oncemtx);
 }



-- 
ryo shimizu


Re: aarch64 gcc kernel compilation

2018-07-16 Thread Ryo Shimizu


>>>> Can we drop it? The __uint128_t type is not used anywhere else in
>>>> aarch64 subdirs.

fortunately, we don't use member of fpreg, use just only as container.
Is this patch enough?

cvs -q diff -aup pcb.h reg.h
Index: pcb.h
===
RCS file: /src/cvs/cvsroot-netbsd/src/sys/arch/aarch64/include/pcb.h,v
retrieving revision 1.1
diff -a -u -p -r1.1 pcb.h
--- pcb.h   10 Aug 2014 05:47:38 -  1.1
+++ pcb.h   17 Jul 2018 04:59:37 -
@@ -45,6 +45,10 @@ struct md_coredump {
struct fpreg fpreg;
 };
 
+/* fpreg should be aligned 16 */
+CTASSERT((offsetof(struct pcb, pcb_fpregs) & 15) == 0);
+CTASSERT((offsetof(struct md_coredump, fpreg) & 15) == 0);
+
 #elif defined(__arm__)
 
 #include 
Index: reg.h
===
RCS file: /src/cvs/cvsroot-netbsd/src/sys/arch/aarch64/include/reg.h,v
retrieving revision 1.2
diff -a -u -p -r1.2 reg.h
--- reg.h   1 Apr 2018 04:35:03 -   1.2
+++ reg.h   17 Jul 2018 04:58:07 -
@@ -44,14 +44,14 @@ struct reg {
 
 union fpelem {
uint64_t u64[2];
-   __uint128_t u128[1] __aligned(16);
+   /* __uint128_t u128[1] __aligned(16); */
 };
 
 struct fpreg {
union fpelem fp_reg[32];
uint32_t fpcr;
uint32_t fpsr;
-};
+} __aligned(16);
 
 #elif defined(__arm__)
 

-- 
ryo shimizu


Re: aarch64 gcc kernel compilation

2018-07-16 Thread Ryo Shimizu


>Gcc is now working on aarch64 but the kernel does not compile because of
>some idiomatic clang code that is not supported by gcc (at least gcc-6)
>
>To define constants, it uses:
>
>static const uintmax_t
>FOO = __BIT(9),
>BAR = FOO;
>
>While this is nice, specially for the debugger, it produces an error
>in gcc. While fixing these is easy, gcc also complains about using the
>constants as switch labels. Thus it is better to just nukem all and
>rewrite them as:
>
>#define FOO __BIT(9)
>#define BAR FOO
>
>Should I go ahead and do it, or there is a smarter solution?

Yes, please!
I tested with below script in my environment (clang), there seems to be no 
problem.


perl -i.old a64armreg_conv.pl aarch64/include/armreg.h

# a64armreg_conv.pl
while (<>) {
if (m#^static\s+(const\s*)?uintmax_t\s*(//.*)?$#) {
} elsif (m#^\s*(\w+)\s*=\s*(.*?)[,;]\s*//(.*)$#) {
print "#define $1   $2  //$3\n";
} elsif (m#^\s*(\w+)\s*=\s*(.*?)[,;]\s*$#) {
print "#define $1   $2\n";
} else {
print;
}
}

-- 
ryo shimizu


Re: amd64 profiling kernel build failure

2016-01-08 Thread Ryo Shimizu
\
 }
 
 #ifdef _KERNEL
-#ifdef MULTIPROCESSOR
-__cpu_simple_lock_t __mcount_lock;
-
-static inline void
-MCOUNT_ENTER_MP(void)
-{
-   __cpu_simple_lock(&__mcount_lock);
-   __insn_barrier();
-}
-
-static inline void
-MCOUNT_EXIT_MP(void)
-{
-   __insn_barrier();
-   __mcount_lock = __SIMPLELOCK_UNLOCKED;
-}
-#else
-#define MCOUNT_ENTER_MP()
-#define MCOUNT_EXIT_MP()
-#endif
-
 static inline void
 mcount_disable_intr(void)
 {
@@ -125,13 +99,8 @@ mcount_write_psl(u_long ef)
__asm volatile("pushl %0; popfl" : : "r" (ef));
 }
 
-#defineMCOUNT_ENTER
\
-   s = (int)mcount_read_psl(); \
-   mcount_disable_intr();  \
-   MCOUNT_ENTER_MP();
-
-#defineMCOUNT_EXIT         
\
-   MCOUNT_EXIT_MP();   \
-   mcount_write_psl(s);
+#define MCOUNT_ENTER   \
+   do { s = (int)mcount_read_psl(); mcount_disable_intr(); } while (0)
+#define MCOUNT_EXITdo { mcount_write_psl(s); } while (0)
 
 #endif /* _KERNEL */


--
ryo shimizu