[ofa-general] Re: [PATCH] opensm/osm_multicast.c: bug with joining/leaving mcast group
Yevgeny Kliteynik
kliteyn at dev.mellanox.co.il
Mon Nov 10 11:18:19 PST 2008
Hi Sasha,
Sasha Khapyorsky wrote:
> Hi Yevgeny,
>
> On 16:36 Mon 10 Nov , Yevgeny Kliteynik wrote:
>> I think there's a bug in the osm_mgrp_add/remove_port functions.
>> If some mcast group member has JoinState 0x1 (full member),
>> and then new join from the same port received with JoinState
>> 0x2 (non member), OpenSM will reduce number of full members
>> of this group, which eventually might cause group deletion.
>
> Right, isn't this how things should work? When full member updates it
> state to non member the number of full members are reduced, and then
> last full member leaves the MC group is deleted (o15-0.2-1.9).
I thought so too, but turns out that it's wrong:
o15-0.1.11: If SA supports UD multicast, then if an endport joins a
multicast group as specified in o15-0.1.10:, SA shall replace the
endport’s current MCMemberRecord:JoinState component with the logical
OR of the MCMemberRecord:JoinState component with the endport’s current
MCMemberRecord:JoinState component if the endport had joined this
multicast group before.
So the full member doesn't update its state to non-member, but rather
adds additional bit to the JoinState (the non-member).
-- Yevgeny
> Sasha
>
>> Similar problem (only in logically opposite direction) happens
>> when port tries to partially leave mcast group.
>>
>> This patch should fix it.
>>
>> Signed-off-by: Yevgeny Kliteynik <kliteyn at dev.mellanox.co.il>
>> ---
>> opensm/opensm/osm_multicast.c | 33 +++++++++++----------------------
>> 1 files changed, 11 insertions(+), 22 deletions(-)
>>
>> diff --git a/opensm/opensm/osm_multicast.c b/opensm/opensm/osm_multicast.c
>> index d62d585..350fd22 100644
>> --- a/opensm/opensm/osm_multicast.c
>> +++ b/opensm/opensm/osm_multicast.c
>> @@ -172,17 +172,11 @@ osm_mcm_port_t *osm_mgrp_add_port(IN osm_subn_t *subn, osm_log_t *log,
>> p_mgrp->last_change_id++;
>> }
>>
>> - if ((join_state ^ prev_join_state) & IB_JOIN_STATE_FULL) {
>> - if (join_state & IB_JOIN_STATE_FULL) {
>> - if (++p_mgrp->full_members == 1) {
>> - mgrp_send_notice(subn, log, p_mgrp, 66);
>> - p_mgrp->to_be_deleted = 0;
>> - }
>> - } else if (--p_mgrp->full_members == 0) {
>> - mgrp_send_notice(subn, log, p_mgrp, 67);
>> - if (!p_mgrp->well_known)
>> - p_mgrp->to_be_deleted = 1;
>> - }
>> + if ((join_state & IB_JOIN_STATE_FULL) &&
>> + !(prev_join_state & IB_JOIN_STATE_FULL) &&
>> + (++p_mgrp->full_members == 1)) {
>> + mgrp_send_notice(subn, log, p_mgrp, 66);
>> + p_mgrp->to_be_deleted = 0;
>> }
>>
>> return (p_mcm_port);
>> @@ -224,17 +218,12 @@ int osm_mgrp_remove_port(osm_subn_t *subn, osm_log_t *log, osm_mgrp_t *mgrp,
>>
>> /* no more full members so the group will be deleted after re-route
>> but only if it is not a well known group */
>> - if ((port_join_state ^ new_join_state) & IB_JOIN_STATE_FULL) {
>> - if (port_join_state & IB_JOIN_STATE_FULL) {
>> - if (--mgrp->full_members == 0) {
>> - mgrp_send_notice(subn, log, mgrp, 67);
>> - if (!mgrp->well_known)
>> - mgrp->to_be_deleted = 1;
>> - }
>> - } else if (++mgrp->full_members == 1) {
>> - mgrp_send_notice(subn, log, mgrp, 66);
>> - mgrp->to_be_deleted = 0;
>> - }
>> + if ((port_join_state & IB_JOIN_STATE_FULL) &&
>> + !(new_join_state & IB_JOIN_STATE_FULL) &&
>> + (--mgrp->full_members == 0)) {
>> + mgrp_send_notice(subn, log, mgrp, 67);
>> + if (!mgrp->well_known)
>> + mgrp->to_be_deleted = 1;
>> }
>>
>> return ret;
>> --
>> 1.5.1.4
>>
>
More information about the general
mailing list