Migrate to new if_clone KPI and implement netlink support
for gif(4). Also break GIFSOPTS ioctl logic out of gif_ioctl.
Details
Diff Detail
- Repository
- rG FreeBSD src repository
- Lint
Lint Passed - Unit
No Test Coverage - Build Status
Buildable 74634 Build 71517: arc lint + arc unit
Event Timeline
| sys/net/if_gif.c | ||
|---|---|---|
| 106 | Why introduce a macro? Other operations on git_ioctl_sx just use the sx(9) interface directly. | |
| 349 | I don't think this really makes sense: the interface is about to go away, so why try to optimize for other threads accessing it? | |
| 700 | Why do we no longer bring the interface down in this case? | |
| sys/net/if_gif.c | ||
|---|---|---|
| 106 | Simply because other drivers are implemented similarly. | |
| 349 | It's not an optimization. | |
| 700 | We will do this in gif_clone_destroy after setting ifp->if_sofc to null and downgrading our lock to ensure dump_nl returns early. | |
| sys/net/if_gif.c | ||
|---|---|---|
| 349 | What exactly is happening? Your explanation doesn't make sense to me, it sounds like there is a deeper bug and downgrading the lock just happens to hide it. Eh, ok, so further below we release our ifp reference, but meanwhile, the link state change is being handled asynchronously, and there is nothing ensuring that the ifp won't be freed. There is even a comment in if_link_state_change() which points out the bug: /* XXXGL: reference ifp? */. Downgrading the lock just happens to hide the bug if you're lucky, but that's not the right solution. What's the purpose of bringing the interface down to begin with if we're about to destroy the interface? | |
| sys/net/if_gif.c | ||
|---|---|---|
| 349 | Thank you for your review.
Yes, there is a deeper problem, and no, I'm not trying to hide it by downgrading. Here is the problem: Drivers can ensure the softc pointer is consistent using rmlock/rwlock like geneve(4), or they can downgrade their lock (which I'm proposing) like below: gif_clone_dump_nl() ... sx_slock(&gif_ioctl_sx); sc = ifp->if_softc; if (sc == NULL) goto ret;
netlink does it for us.
It's not a problem of if_link_state_change() because anyone can call dump_nl in another thread at the same time. | |
| sys/net/if_gif.c | ||
|---|---|---|
| 349 |
What does downgrading the lock accomplish, specifically? If we do not downgrade, then gif_clone_dump_nl() will block on the ioctl lock until gif_clone_destroy() releases the lock. When it finally acquires the lock it'll observe if_softc == NULL and return. Can you provide more details on the crash or hang that you saw? Basically, I am very skeptical that downgrading a lock can ever be the correct solution to a hang or crash. At best it is making the bug harder to hit.
That is too late. It needs to be done before the task is scheduled. Look at do_link_state_change(): what is keeping the ifnet alive while it is running eventhandlers etc.? | |
| sys/net/if_gif.c | ||
|---|---|---|
| 349 |
After moving if_link_state_change() out of gif_delete_tunnel(), I'm not able to reproduce that, not sure why, maybe that's enough and I was wrong.
There are multiple benefits to downgrading the lock, particularly in the case of clone_destroy:
Downgrading a lock prevents another thread to acquire an exclusive lock without pausing other read operations.
The caller is responsible for this. In contrast to if_gre, we actually can continue without lock downgrade, but I believe it could be unsafe to do so. | |