-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bluetooth: Replace custom rand driver with standard entropy #6294
Bluetooth: Replace custom rand driver with standard entropy #6294
Conversation
CC @durub |
# FIXME: nRF5 RNG driver can't co-exist with Bluetooth's HAL | ||
# implementation yet | ||
depends on ENTROPY_GENERATOR && !BT | ||
depends on ENTROPY_GENERATOR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bump copyright year
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is done.
drivers/entropy/Kconfig.nrf5
Outdated
config ENTROPY_NRF5_PRI | ||
int "RNG interrupt priority" | ||
depends on ENTROPY_NRF5_RNG | ||
range 0 1 if SOC_SERIES_NRF51X |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isnt 3 level of priority available now in Zephyr CM0? and 5 in CM4?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not in CM4, but you are correct about CM0
drivers/entropy/Kconfig.nrf5
Outdated
depends on ENTROPY_NRF5_RNG | ||
range 0 1 if SOC_SERIES_NRF51X | ||
range 0 5 if SOC_SERIES_NRF52X | ||
default 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let keep this all the way to the lowest
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK
drivers/entropy/entropy_nrf5.c
Outdated
|
||
#define RAND_DEFINE(name, len) u8_t name[sizeof(struct rand) + len] __aligned(4) | ||
|
||
#define RAND_THREAD_THRESHOLD 4 /* at least access address */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have these as Kconfig options, and checked by controller Kconfig?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK
include/entropy.h
Outdated
* @retval bytes filled on success. | ||
* @retval -ERRNO errno code on error. | ||
*/ | ||
int entropy_nrf5_isr_get_entropy(struct device *device, u8_t *buf, u16_t len); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
drop nrf5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then I would have to include it in the API and I want to avoid this at this point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will wait for @galak
Codecov Report
@@ Coverage Diff @@
## master #6294 +/- ##
=======================================
Coverage 53.51% 53.51%
=======================================
Files 437 437
Lines 41420 41420
Branches 7935 7935
=======================================
Hits 22164 22164
Misses 16039 16039
Partials 3217 3217 Continue to review full report at Codecov.
|
ec344da
to
4c14298
Compare
@GiulianoFranchetto this would solve the issues in #6049 |
drivers/entropy/entropy_nrf5.c
Outdated
|
||
#define RAND_DEFINE(name, len) u8_t name[sizeof(struct rand) + len] __aligned(4) | ||
|
||
#define RAND_THREAD_LEN (CONFIG_ENTROPY_NRF5_THR_THRESHOLD + 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need two more.... CONFIG_ENTROPY_NRF5_THR/ISR_SIZE, these have the "range CONFIG_ENTROPY_NRF5_THR/ISR_THRESHOLD 255"
and use (CONFIG_ENTROPY_NRF5_THR/ISR_SIZE + 1) as the context-safe ring buffer size.
# FIXME: nRF5 RNG driver can't co-exist with Bluetooth's HAL | ||
# implementation yet | ||
depends on ENTROPY_GENERATOR && !BT | ||
depends on ENTROPY_GENERATOR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is done.
pdu_ctrl_tx->llctrl.enc_rsp.skds); | ||
rand_isr_get(sizeof(pdu_ctrl_tx->llctrl.enc_rsp.ivs), | ||
pdu_ctrl_tx->llctrl.enc_rsp.ivs); | ||
entropy_nrf5_isr_get_entropy(_radio.entropy, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check if these additional parameter passing has ISR overheads.
4c14298
to
9e2510f
Compare
@cvinayak addressed all your comments, including the generic API instead of an nrf5 one |
9e2510f
to
c0cc6df
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some changes to consider.
} | ||
struct device *entropy; | ||
|
||
entropy = device_get_binding(CONFIG_ENTROPY_NAME); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this either use the entropy handle from the radio, or is there somewhere we can initialize this once, so we don't have to call device_get_binding on every call to bt_rand()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I plan to change bt_rand later anyway, and this is only used by the BLE Host sparingly.
include/entropy.h
Outdated
* @retval bytes filled on success. | ||
* @retval -ERRNO errno code on error. | ||
*/ | ||
static inline int entropy_isr_get_entropy(struct device *dev, u8_t *buffer, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about we have _isr at the end of the function as the naming convention, I think that will be cleaner going forward (entropy_get_entropy_isr)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, will change
include/entropy.h
Outdated
{ | ||
const struct entropy_driver_api *api = dev->driver_api; | ||
|
||
__ASSERT(api->isr_get_entropy, "Callback pointer should not be NULL"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should do something like:
if (api->isr_get_entropy) {
return ...
} else {
return -ENOTSUP;
}
Since not every driver might support this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, will change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is one additional branching in ISR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only with kernel asserts enabled (CONFIG_DEBUG
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
drivers/entropy/entropy_nrf5.c
Outdated
|
||
struct entropy_nrf5_dev_data { | ||
atomic_t user_count; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
redundant line.
subsys/bluetooth/controller/Kconfig
Outdated
select ENTROPY_GENERATOR | ||
select ENTROPY_NRF5_RNG if SOC_FAMILY_NRF5 | ||
select ENTROPY_NRF5_BIAS_CORRECTION if SOC_FAMILY_NRF5 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
redundant line?
entropy_isr_get_entropy(_radio.entropy, | ||
pdu_ctrl_tx->llctrl.enc_rsp.skds, | ||
sizeof(pdu_ctrl_tx->llctrl.enc_rsp.skds)); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
redundant line
entropy_isr_get_entropy(_radio.entropy, | ||
pdu_ctrl_tx->llctrl.enc_req.skdm, | ||
sizeof(pdu_ctrl_tx->llctrl.enc_req.skdm)); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
redundant line
c0cc6df
to
bc9d583
Compare
I'm analyzing the algorithm. I will put opinion soon. |
|
||
ret = isr((struct rand *)dev_data->isr, true); | ||
if (ret != -EBUSY) { | ||
ret = isr((struct rand *)dev_data->thr, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this call is made? Is this for flush random value in case of the race condition occurrence?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^^I mean the second param value - -ENOBUFS
might be returned in two cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-ENOBUFS is returned to convey that a new rng value has not been put into ring buffer due to the ISR ring buffer being full (or no ISR ring buffer initialized). Hence, conveyed as "store" param to the next ring buffer (thread).
Same pattern of nested if-clause can be used to scale to any number of ring buffer population.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Then i understood this properly. Everything is right here.
drivers/entropy/entropy_nrf5.c
Outdated
last = rng->last; | ||
|
||
if (first <= last) { | ||
u8_t *d, *s; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
u8_t *d, *s;
u8_t avail;
d = &rand[octets];
s = &rng->rand[first];
Put before if statement - this are code duplication.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree.
@nvlsianpu I didn't write the driver, just ported it, so I will let @cvinayak speak about the implementation details. |
drivers/entropy/entropy_nrf5.c
Outdated
d = &rand[octets]; | ||
s = &rng->rand[first]; | ||
|
||
avail = rng->count - first; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we have a comment here? - like fetch bytes form upper part of random buffer.
drivers/entropy/entropy_nrf5.c
Outdated
} | ||
|
||
if (octets && last) { | ||
s = &rng->rand[0]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we have a comment here? - like fetch bytes form lower part of random buffer.
drivers/entropy/entropy_nrf5.c
Outdated
}; | ||
|
||
#define DEV_DATA(dev) \ | ||
((struct entropy_nrf5_dev_data *)(dev)->driver_data) | ||
|
||
static inline u8_t entropy_nrf5_get_u8(void) | ||
static size_t get(struct rand *rng, size_t octets, u8_t *rand) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is possible to reorganize get algorithm to two if statement:
if (last < first) {
// fetch bytes from upper rng buffer
// update first, last, octets
}
if (octets && (first <= last)
{
// fetch bytes from lower rng buffer
}
I don't see a big sense in do so - so I just I signal this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your suggestion translates to:
1 compare and 1 branch
plus
1 branch, 1 compare and 1 branch
whereas my top level if-clause translates to just 1 compare and 1 branch (my understanding).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, something like this. Code would be more compact, but cons is increased execution time.
so keep as is.
drivers/entropy/entropy_nrf5.c
Outdated
}; | ||
|
||
#define DEV_DATA(dev) \ | ||
((struct entropy_nrf5_dev_data *)(dev)->driver_data) | ||
|
||
static inline u8_t entropy_nrf5_get_u8(void) | ||
static size_t get(struct rand *rng, size_t octets, u8_t *rand) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your suggestion translates to:
1 compare and 1 branch
plus
1 branch, 1 compare and 1 branch
whereas my top level if-clause translates to just 1 compare and 1 branch (my understanding).
drivers/entropy/entropy_nrf5.c
Outdated
last = rng->last; | ||
|
||
if (first <= last) { | ||
u8_t *d, *s; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree.
|
||
ret = isr((struct rand *)dev_data->isr, true); | ||
if (ret != -EBUSY) { | ||
ret = isr((struct rand *)dev_data->thr, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-ENOBUFS is returned to convey that a new rng value has not been put into ring buffer due to the ISR ring buffer being full (or no ISR ring buffer initialized). Hence, conveyed as "store" param to the next ring buffer (thread).
Same pattern of nested if-clause can be used to scale to any number of ring buffer population.
bc9d583
to
a721f29
Compare
a721f29
to
93319e3
Compare
@cvinayak pushed a fix for the crash. The issue was the wrong pointer passed to |
@nvlsianpu @galak this should be ready now |
93319e3
to
0eeeb27
Compare
#ifndef _NRF5_ENTROPY_H_ | ||
#define _NRF5_ENTROPY_H_ | ||
|
||
int entropy_get_entropy_thr(u8_t *buf, u16_t len); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you are using these outside of the driver, should have a bit more comment/api docs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why aren't we adding these APIs entropy_get_entropy_isr & entropy_get_entropy_thr to include/entropy.h?
If they are not going to be added there, they should have an nrf namespace.
0eeeb27
to
2e6a132
Compare
Because the issue is removing the |
How much faster? Faster that what other implementation? One in which we pass a pointer to the entropy device? |
The issue here is that we want to be able to use a standard entropy driver for the Link Layer, which has strict timing requirements. What @cvinayak has observed is that if we don't remove the parameter from the function call, as well as optimizing with |
drivers/entropy/entropy_nrf5.c
Outdated
return 0; | ||
} | ||
|
||
int entropy_get_entropy_thr(u8_t *buf, u16_t len) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cvinayak do we really need this one? In thread mode we could use the standard one really
2e6a132
to
c52be4c
Compare
#include "hal/ecb.h" | ||
#include "hal/ccm.h" | ||
#include "hal/radio.h" | ||
#include "hal/debug.h" | ||
#include "hal/radio.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
duplicated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
@@ -6,23 +6,28 @@ | |||
|
|||
#include <soc.h> | |||
|
|||
#if defined(CONFIG_SOC_FAMILY_NRF5) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you dont need this here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
@@ -5831,7 +5833,7 @@ static u32_t access_addr_get(void) | |||
LL_ASSERT(retry); | |||
retry--; | |||
|
|||
bt_rand(&access_addr, sizeof(u32_t)); | |||
bt_rand((u8_t *)&access_addr, sizeof(u32_t)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
redundant change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
c52be4c
to
8aa8a2a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@galak we leave this out of 1.11, ready for 1.12. That said, it still needs your approval, I think all of your initial objections have been addressed. |
LGTM. Thanks, @carlescufi! I was just needing this yesterday, having this ready for 1.12 is great news -- good job. |
9803006
to
b43d63e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
The rand driver present in the BLE Link Layer is able to provide entropy for both threads and ISRs, and so it is more suited to be used as a generic nRF5x entropy driver instead of the current one. This will allow applications and the Link Layer to use the same driver without duplicating it. Signed-off-by: Carles Cufi <[email protected]> Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
b43d63e
to
d884038
Compare
After porting the rand driver to drivers/entropy, replace the usage of the old, Buetooth-specific driver with the generic entropy one. Signed-off-by: Carles Cufi <[email protected]> Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
d884038
to
df4390f
Compare
No description provided.